整型

TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT分别使用1,2,3,4,8字节的存储空间。

可以使用UNSIGNED属性表示不允许负值以提高正数的上限,但有符号和无符号类型的存储空间和性能依旧一样。

MySQL可以为整数类型指定宽度,如INT(11),但它不会限制值的合法范围,只是规定了交互工具显示字符的个数。

浮点数

FLOATDOUBLE为浮点类型(浮点数),DECIMAL为高精度小数类型(定点数)。

CPU原生支持浮点运算,但不支持对DECIMAL的运算,因此浮点运算会更快。但是浮点数会引起精度问题,像货币这样对精度敏感的数据,应该用DECIMAL来存储。

浮点和定点都可以指定精度,例如DECIMAL(18, 9)表示总共18位,取9位存储小数部分,剩下9位存储整数部分。

字符串

MySQL主要有VARCHARCHAR两种字符串类型。

VARCHAR类型是可变长的,它比定长类型更节省空间,因为它仅使用必要的空间。但是在执行UPDATE时可能会使行变得比原来长,当超出一个页所能容纳的大小时,就要执行额外的操作,MyISAM会将行拆成不同的片段存储,InnoDB则需要分裂页来使行放进页内。

CHAR类型是定长的,总是根据定义的字符串长度分配足够的空间,并且在存储和检索时删除末尾的空格,而VARCHAR是会保留末尾的空格的。

当字符串列的长度比平均长度大很多时、列的更新很少时,使用VARCHAR类型更好;对于定长的字符串如MD5、经常变更或者非常短的字符串(因为VARCHAR需要额外的1个或2个字节记录字符串长度)则使用CHAR类型更好。

日期和时间

MySQL提供两种相似的日期类型:DATETIMETIMESTAMP

DATETIME能够保存从1001年到9999年的日期和时间,精度为秒。它把日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关,使用8个字节的存储空间。默认情况下,MySQL以一种可排序的、无歧义的格式显示,例如2008-01-16 22:37:08

TIMESTAMP保存从1970年1月1日午夜(格林威治时间)以来的秒数,使用4个字节,只能表示从1970年到2038年。这种类型的时间是和时区有关的,默认情况下,如果插入时没有指定TIMESTAMP列的值,MySQL则设置这个列的值为当前时间。

应该尽量使用TIMESTAMP,因为它比DATETIME空间效率更高。