选择原则
- 更小的通常更好
一般情况下,应该尽量使用可以正确存储数据的最小数据类型(比如只需要存0-200,选择tinyint unsigned更好)。更小的数据类型通常更快,因为它们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。
- 简单就好
简单数据类型的操作通常需要更少的CPU周期
- 尽量避免NULL
如果查询中包含可为NULL的列,对MySQL来说更难优化,因为可为NULL的列使得索引、索引统计和值比较都更复杂。可为NULL的列会使用更多的存储空间,在MySQL里也需要特殊处理
整数类型
有两种类型的数字:整数和实数,可以使用这几种整数类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。分别使用8,16,24,32,64位存储空间。
整数类型有可选的UNSIGNED属性,表示不允许负值。
MySQL可以为整数类型指定宽度,例如INT(11) ,对大多数应用这是没有意义的:它不会限制值的合法范围,只是规定了MySQL的一些交互工具用来显示字符的个数。对于存储和计算来说,INT(1)和INT(20)是相同的。
实数类型
实数是带有小数部分的数字。然而,它们不只是为了存储小数部分;也可以使用DECIMAL存储比BIgint还大的整数。MySQL即支持精确类型,也支持不精确类型。
DECIMAL类型用于存储精确的小数。在MySQL5.0和高版本中,支持精确计算。
对于DECIMAL列,可以指定小数点前后所允许的最大位数。这会影响列的空间消耗。MySQL5.0和高版本中,将数字打包保存到一个二进制字符串中(每4个字节存九个数字)
字符串类型
VARCHAR
VARCHAR类型用于存储可变长字符串,是最常见的字符串数据类型。它比定长类型更节省空间,因为它仅使用必要的空间。
VARCHAR需要使用1或2个额外字节记录字符串的长度:如果列的最大长度小于或等于255字节,则只使用一个字节表示,否则使用2个字节。 假设采用latin1字符集,一个VARCHAR(10)需要11个字节存储空间。VARCHAR(1000)需要1002个字节存储空间
以下情况适合VARCHAR:
- 字符串列的最大长度比平均长度大很多;列的更新很少,所以碎片不是问题
- 使用了像UTF-8这种复杂的字符集,每个字符都是用不同的字节数进行存储
CHAR
CHAR类型是定长的:MySQL总是根据定义的字符串长度分配足够的空间。存储CHAR值时,MySQL会删除所有的末尾空格。CHAR值会根据需要采用空格进行填充以方便比较
以下情况适合CHAR:
- CHAR非常适合存储密码的MD5值
- 对于经常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR类型不容易产生随便
- 对于非常短的列,CHAR比VARCHAR在存储空间上更有效率
BLOB和TEXT类型
两者都是为存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。
它们分别属于两组不同的数据类型家族:字符类型是TINYTEXT,SMALLTEXT,TEXT,MEDIUMTEXT,LONGTEXT;对应的二进制类型是TINYBLOB,SMALLBLOB,BLOB,MEDIUMBLOB,LONGBLOB。BLOB是SMALLBLOB的同义词,TEXT是SMALLTEXT的同义词
日期和时间类型
DATETIME
这个类型能保存大范围的值,从1001年到9999年,精度为秒。它把日期和时间封装到格式为YYYYMMDDHHMMSS的整数中,与时区无关。使用8个字节的存储空间。
默认情况下,MySQL以一种可排序的、无歧义的格式显示DATETIME值,例如“2008-01-16 22:37:08”
TIMESTAMP
该类型保存了从1970年1月1日午夜(格林尼治标准时间)以来的秒数,它和UNIX时间戳相同。只使用4个字节的存储空间.TIMESTAMP显示的值也依赖于时区。
TIMESTAMP提供的值与时区有关系,后者则保留文本表示的日期和时间。
默认情况下,如果插入时没有指定第一个TIMESTAMP列的值,MySQL则设置这个列的值为当前时间。TIMESTAMP列默认为NOT NULL。
通常尽量使用TIMESTAMP,因为它比DATETIME空间效率更高
位数据类型
BIT
BIT(1)表示包含单个位的字段,BIT(2)存储2个位,以此类推。BIT列的最大长度是64位
SET
如果需要保存很多true/false值,可以考虑合并这些列到一个SET数据类型,它在MySQL内部是以一系列打包的位的集合来表示。