MySQL 中数据类型常用的就三大类:
- 数字类型/numeric types
- 日期和时间/date and time types
- 字符类型/string (character and byte) types
另外还包含两个没那么常用的大类:
- 特殊类型/spatial types
- JSON
继续之前,先来看一些单位上的约定和概念,
- M:根据具体不同的类型,其表示的意思不一样,见下方关于这个参数的讨论。
- D 用于定点及浮点数,表示小数点后有多少位。最大可能取值为 30,但不应该超过 M-2。
- fsp 适用于 TIME, DATETIME 及 TIMESTAMP。可理解秒后面的小数点位数。它应该是介于 0~6 之间的,0 表示没有小数部分(fractin part)。默认为 0。
[]
方括号表示类型中可选的部分。
存储字符串时指定的类型 VARCHAR(50)
中可接收一个数字作为长度,其实除了字符串类型,数字类型也是可指定该参数的,比如 INT(10)
,BIGINT(20)
。假设后续讨论中这个参数使用字母 M 来表示,即上面提到的。该参数被用在不同类型上时,其表示的意思不一样。
- 对于整形,它表示 展示宽度/display width。
- 对于定点数(fixed point)或浮点数(floating point),表示能够存储的总位数,即精度。
- 对于字符串,表示能够存储的字符串长度。
展示宽度/Display Width
那么什么是展示宽度。展示宽度这个参数具有迷惑性,它不像 CHAR(M)
中有实际意义表示能够存储的字符串长度,在数字类型中,它指数字展示时需要的宽度,是 MySQL 格式化时使用的。即 INT(5)
,INT(15)
,INT(25)
能够存储的数字范围都是 INT
类型的范围 -2147483648 ~ 2147483647。如果指定了 ZEROFILL
,MySQL 在返回该数字时,对于实际位数小于展示宽度的数字,将自动在左边补零。比如列的类型为 INT(5)
,实际存储了数字 5,返回时会得到 00005
。对于没有指定 ZEROFILL
或实际存储的位数大于指定的展示宽度,则不会自动补零,此时看上去没有任何效果。
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)
另外,如果使用了 ZEROFILL
,该列将自动设置为 UNSIGNED
类型。
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 信息以获取到相应的展示宽度。
假如在 Node.js 中使用 mysqljs/mysql 作为数据库连