p147~p176.
数据类型优化的简单原则
- 更小的通常更好.
- 简单就好.
- 尽量避免NULL.
整数类型
- TINYINT(8), SMALLINT(16), MEDIUMINT(24), INT(32), BIGINT(64).
- 所有整数类型可以加上UNSIGNED表示无符号数, 如
TINYINT UNSIGNED
. - 整数类型可以指定宽度, 不会限制值的合法范围. 如int(11)与int(20)是一样的.
小数
- 精确类型, DECIMAL, 一般用于存储财务数据. 数据量比较大的时候, 可以考虑用BIGINT代替DECIMAL, 将数据乘以相应的倍数.
- 不精确类型, FLOAT和DOUBLE.
字符串类型
每个字符串可以定义自己的字符集和排序规则.
VARCHAR类型
- 可以存储可变长字符串, 需要使用1或2个额外字节记录字符串长度.
- UPDATE可能是行变得比原来长, 在一个页内无法放下, 导致一行无法放在一个页内, 这时MyISAM会将行拆成不同的片段存储, InnoDB需要分裂页, 生成一个新页来存储这个行.
- 适用情况: 字符串列的最大长度比平均长度大很多, 列的更新很少, 所以碎片不是问题; 使用了像UTF-8这样复杂的字符集, 每个字符使用不同的长度进行存储.
- InnoDB将过长的VARCHAR存储为BLOB.
CHAR类型
- 类型定长, MySQL总是根据定义的字符串长度分配足够的空间. 删除末尾空格.
- 适合存储固定长度的字符串, 如MD5值,
VARCHAR(5)与VARCHAR(200)的存储开销相同, 但是更长的列消耗的内存更多, 尤其适用内存临时表进行排序或操作.
BLOB类型和TEXT类型
- TINYBLOB, SMALLBLOB, BLOB, MEDIUMBLOB, LONGBLOB. BLOB = SMALLBLOB. TEXT类型类似.
- MySQL把BLOB和TEXT值当作一个独立的对象处理. 值太大时, InnoDB使用"外部"存储区域来进行存储. 此时每个值在行内需要1~4个字节存储一个指针, 然后在外部存储实际值.
- 区别: BLOB类型存储的是二进制数据, 没有排序规则和字符集, TEXT有.
- 排序的特殊: 只对每个列的最前max_sort_length字节而不是整个字符串做排序. 若只需要排序前面一小部分字符, 则使用ORDER BY SUSTRING(column, length).
SET max_length_for_sort_data = 1024;
SHOW VARIABLES LIKE '%max_length_for_sort_data%';