MySQL 中数据类型经常使用的就三大类:php
另外还包含两个没那么经常使用的大类:html
继续以前,先来看一些单位上的约定和概念,mysql
存储字符串时指定的类型
展现宽度/Display Width那么什么是展现宽度。展现宽度这个参数具备迷惑性,它不像 CREATE TABLE test_zero_fill
(
with_fill INT(5) UNSIGNED ZEROFILL NOT NULL PRIMARY KEY,
without_fill INT(5) UNSIGNED NOT NULL
);
mysql> INSERT INTO test_zero_fill (with_fill, without_fill) VALUES (5, 5),(123456, 123456);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from test_zero_fill;
+-----------+--------------+
| with_fill | without_fill |
+-----------+--------------+
| 00005 | 5 |
| 123456 | 123456 |
+-----------+--------------+
2 rows in set (0.00 sec)
另外,若是使用了 mysql> ALTER TABLE test_zero_fill ADD signed_num INT(5) signed ZEROFILL NOT NULL after without_fill;
mysql> describe test_zero_fill;
+--------------+--------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------------------+------+-----+---------+-------+
| with_fill | int(5) unsigned zerofill | NO | PRI | NULL | |
| without_fill | int(5) unsigned | NO | | NULL | |
| signed_num | int(5) unsigned zerofill | NO | | NULL | |
+--------------+--------------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
因此对于数据存储层面来讲,展现宽度其实没什么用途。若是真的须要格式化,程序中可以请求 MySQL 的 meta 信息以获取到相应的展现宽度。shell 假如在 Node.js 中使用 mysqljs/mysql 做为数据库链接的模块,在执行请求时,其回调中返回的 connection.query("SELECT * from test_zero_fill", function(
error,
results,
fields
) {
if (error) throw error;
console.log(fields);
});
FieldPacket {
catalog: 'def',
db: 'data_type',
table: 'test_zero_fill',
orgTable: 'test_zero_fill',
name: 'with_fill',
orgName: 'with_fill',
charsetNr: 63,
length: 5,
type: 3,
flags: 20579,
decimals: 0,
default: undefined,
zeroFill: true,
protocol41: true
},
FieldPacket {
catalog: 'def',
db: 'data_type',
table: 'test_zero_fill',
orgTable: 'test_zero_fill',
name: 'without_fill',
orgName: 'without_fill',
charsetNr: 63,
length: 5,
type: 3,
flags: 4129,
decimals: 0,
default: undefined,
zeroFill: false,
protocol41: true
},
FieldPacket {
catalog: 'def',
db: 'data_type',
table: 'test_zero_fill',
orgTable: 'test_zero_fill',
name: 'signed_num',
orgName: 'signed_num',
charsetNr: 63,
length: 5,
type: 3,
flags: 4193,
decimals: 0,
default: undefined,
zeroFill: true,
protocol41: true
}
]
所以,在设计表时,应该关注使用哪一种具体的数据类型可以知足数据存储的须要,而不要被展现宽度所迷惑。ui 数字类型数字类型分为有符号 整型MySQL 中支持标准的 SQL 整型,
而且扩展了一些类型:
如下是 MySQL 中支持的整型,及其对应所需存储空间和取值范围。
具体到每种类型:
mysql> SELECT IF(0, 'true', 'false');
+------------------------+
| IF(0, 'true', 'false') |
+------------------------+
| false |
+------------------------+
mysql> SELECT IF(1, 'true', 'false');
+------------------------+
| IF(1, 'true', 'false') |
+------------------------+
| true |
+------------------------+
mysql> SELECT IF(2, 'true', 'false');
+------------------------+
| IF(2, 'true', 'false') |
+------------------------+
| true |
+------------------------+
mysql> SELECT IF(0 = FALSE, 'true', 'false');
+--------------------------------+
| IF(0 = FALSE, 'true', 'false') |
+--------------------------------+
| true |
+--------------------------------+
mysql> SELECT IF(1 = TRUE, 'true', 'false');
+-------------------------------+
| IF(1 = TRUE, 'true', 'false') |
+-------------------------------+
| true |
+-------------------------------+
mysql> SELECT IF(2 = TRUE, 'true', 'false');
+-------------------------------+
| IF(2 = TRUE, 'true', 'false') |
+-------------------------------+
| false |
+-------------------------------+
mysql> SELECT IF(2 = FALSE, 'true', 'false');
+--------------------------------+
| IF(2 = FALSE, 'true', 'false') |
+--------------------------------+
| false |
+--------------------------------+
关于大整型,关键字 还记得建立表时通常须要指定一个自增的整形 ID 字段么, CREATE TABLE table_name (id INT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT)
CREATE TABLE table_name (id SERIAL PRIMARY KEY)
若是你不想要 BIGINT, CREATE TABLE table_name (id INT SERIAL DEFAULT VALUE PRIMARY KEY)
定点型DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL] 定点型数字,其中 M 表示总的位数(不包含正负号及小数点),D 表示小数位数。D 为 0 则表示没有小数部分。M 最大取值 65,默认 10;D 最大支持到 30,默认 0。全部的算术运算( DEC[(M[,D])] [UNSIGNED] [ZEROFILL], NUMERIC[(M[,D])] [UNSIGNED] [ZEROFILL], FIXED[(M[,D])] [UNSIGNED] [ZEROFILL] 同 定点型数字存储精确的数字,用于准确性要求高的场合,好比涉及金钱。底层实现上,MySQL 使用二进制形式存储该类型的值。 一般的用法以下: salary DECIMAL(5,2)
上面示例中,salary 为一个 5 位精度两位小数的定点型。取值范围 -999.99 ~ 999.99。 由于 D 缺省时默认为 0,因此 当实际存储的值其小数大于指定的位数时,其精度会自动转换成所存储的值的精度。 浮点型区别于 DECIMAL,浮点型存储的数字是个近似值。内部存储时,MySQL 为单精度使用 4 字节(bytes),双精度使用 8 字节。 浮点型包含如下这些类型:
因此实际使用时,为了最大限度的兼容性,直接使用 BIT 类型BIT[(M)] 类型用于存储单个状态值,M 表示包含几位。默认为1,最大可取 64。 该类型的值可经过 若是赋值到该类型上的值小于 M 指定的位数,值左边会补零,好比将 b'101' 存储到类型为 BIT(6) 的列,实际会是 b'000101'。 存储的值溢出的状况将要存储的值超出数字类型的范围时,其表现跟当前设置的 SQL 模式有关。具体来讲,
考察一个经过以下语句建立的表 CREATE TABLE t1 (i1 TINYINT, i2 TINYINT UNSIGNED);
SQL 严格模式下,尝试写入一个超出范围的值时抛错: mysql> SET sql_mode = 'TRADITIONAL';
mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
ERROR 1264 (22003): Out of range value for column 'i1' at row 1
mysql> SELECT * FROM t1;
Empty set (0.00 sec)
如下是非严格模式下进行裁剪存储的状况: mysql> SET sql_mode = '';
mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
mysql> SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'i1' at row 1 |
| Warning | 1264 | Out of range value for column 'i2' at row 1 |
+---------+------+---------------------------------------------+
mysql> SELECT * FROM t1;
+------+------+
| i1 | i2 |
+------+------+
| 127 | 255 |
+------+------+
上述表现一样会出如今涉及到对列进行转换修改的一些操做上,好比 进行数字计算时若是有溢出,也会抛错,好比对于 BIGINT 其最大值为 9223372036854775807,由于 MySQL 中默认对数字类型是有符号类型,以下操做会抛错, mysql> SELECT 9223372036854775807 + 1;
ERROR 1690 (22003): BIGINT value is out of range in '(9223372036854775807 + 1)'
对于上述状况,可显式将 被操做数进行类型转换,转成无符号的 BIGINT: mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1;
+-------------------------------------------+
| CAST(9223372036854775807 AS UNSIGNED) + 1 |
+-------------------------------------------+
| 9223372036854775808 |
+-------------------------------------------+
经过带上小数后,转成 DECIMAL 也能修正上面的错误,由于 DECIMAL 比整形要大, mysql> SELECT 9223372036854775807.0 + 1;
+---------------------------+
| 9223372036854775807.0 + 1 |
+---------------------------+
| 9223372036854775808.0 |
+---------------------------+
两数相减时,其中一个为无符号数,得出的结果默认为也为无符号。因此若是想减以后结果是负数,则会抛错。 mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(cast(0 as unsigned) - 1)'
除非开启了 mysql> SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+
| CAST(0 AS UNSIGNED) - 1 |
+-------------------------+
| -1 |
+-------------------------+
总结对于整型或浮点型,可指定 对于须要精确数值的场合,使用 DECIMAL,好比涉及金钱的状况。 对于整形,展现宽度不是其存储的值范围,只用来格式化。 相关资源 |