一、基本原则
1、更小的通常更好
更小的数据类型通常更快,因为占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。
但是要确保没有低估需要存储的值的范围,因为在schema中的多个地方增加数据类型的范围是个非常耗时的操作。
2、简单就好
例如,整数比字符串操作代价更低,应该用内建类型而不是字符串来存储时间和日期,用整型存储IP。
3、尽量避免NULL
可为NULL的列使用更多的存储空间,需要特殊的处理。特别是可为NULL的列被索引时,每个索引需要额外的字节,在Myisam引擎里甚至还可能导致固定大小的索引,所以计划建立索引的列,要避免使用NULL。
二、数据类型
1、整数类型
TINYINT、SMALLINT、MEDIUINT、INT、BIGINT,分别使用8、16、24、32、64位存储空间。范围从-2(N-1)次方到2(N-1)次方-1。
指定范围,只是一种显示,对存储和计算来说INT(1)和INT(20)是一样的。
2、实数类型
FLOAT和DOUBLE支持使用标准的浮点运算进行近似计算。
DECIMAL类型用于存储精确的小数
浮点类型在存储同样的范围的值是,通常比DECIMAL使用的空间更少。因为额外的空间和计算开销所以应该只在对小数进行精确计算时才使用,也可以考虑使用BIGINT代替DECIMAL,将小数的位数乘以相应的倍数即可。
3、字符串类型
VARCHAR类型用于存储可变长字符串,但是需要1-2个额外字节记录字符串的长度。由于行是变长的,在UPDATE时不同的引擎需要不同的额外处理工作。同时存储和检索时会保留末尾空格。
CHAR类型是定长的。存储时会删除末尾的空格。
对于字符串最大长度比平均长度大很多,列的更新很少,适合VARCHAR。对于经常更新的数据,CHAR更好,因为不容易产生碎片。
4、BLOB和TEXT类型
都是为存储大的数据而设计的字符串类型,分别采用二进制和字符方式存储,BLOB没有排序规则和字符集。
MySQL对BLOB和TEXT列进行排序和其他类型是不同的,它只针对每个列的最前max_sort_length字节排序,或者使用order by substring(column,length).
如果查询使用了BLOB和TEXT列并且需要使用隐式临时表,将不得不用到MYIASM磁盘临时表,这是很大的系统开销。如果无法避免,有一个技巧是在所有使用到BLOB字段的地方使用substring(column,length)将列值转换为字符串,这样就可以使用内存临时表了。但是要确保截取的字符串足够短,不会使临时表的大小超过max_heap_table_size和tmp_table_size,如果超过还是会使用磁盘临时表的。
如果explain的Extra列包含“Using temporary”,则说明用到了隐式临时表
5、ENUM类型
把一些不重复字符串存储成一个预定义的集合,非常节省空间。mysql在内部会将每一个值在列表中的位置保存为整数,并且在表的.frm文件中保存“数字-字符串”的映射关系的查找表。只有在进行查找时才会转化为字符串。