1. char、varchar、text等字符串类型定义
1) 对于长度基本固定的列,如果该列恰好更新又特别频繁,适合char
2) varchar虽然存储变长字符串,但不可太小也不可太大。UTF8最多能存21844个汉字,或65532个英文
3) varbinary(M)保存的是二进制字符串,它保存的是字节而不是字符,所以没有字符集的概念,M长度0-255(字节)。只用于 排序或比较时大小写敏感的类型,不包括密码存储
4) TEXT类型与VARCHAR都类似,存储可变长度,最大限制也是2^16,但是它20bytes以后的内容是在数据页以外的空间存 储 (row_format=dynamic),对它的使用需要多一次寻址,没有默认值。
一般用于存放容量平均都很大、操作没有其它字段那样频繁的值。
网上部分文章说要避免使用text和blob,要知道如果纯用varchar可能会导致行溢出,效果差不多,但因为每行占用字节数 过多,会导致buffer_pool能缓存的数据行、页下降。另外text和blob上面一般不会去建索引,而是利用sphinx之类的第三 方全文搜索引擎,如果确实要创建(前缀)索引,那就会影响性能。凡事看具体场景。
另外尽可能把text/blob拆到另一个表中
5) BLOB可以看出varbinary的扩展版本,内容以二进制字符串存储,无字符集,区分大小写,有一种经常提但不用的场景: 不要在数据库里存储图片。
2.int、tinyint、decimal等数字类型定义
1) 使用tinyint来代替 enum和boolean
ENUM类型在需要修改或增加枚举值时,需要在线DDL,成本较高;ENUM列值如果含有数字类型,可能会引起默认值混淆
tinyint使用1个字节,一般用于status,type,flag的列
2) 建议使用 UNSIGNED 存储非负数值
相比不使用 unsigned,可以扩大一倍使用数值范围
3) int使用固定4个字节存储,int(11)与int(4)只是显示宽度的区别
4) 使用Decimal 代替float/double存储精确浮点数
对于货币、金额这样的类型,使用decimal,如 decimal(9,2)。float默认只能能精确到6位有效数字
3.timestamp与datetime选择
1) datetime 和 timestamp类型所占的存储空间不同,前者8个字节,后者4个字节,这样造成的后果是两者能表示的时间范围 不同。前者范围为1000-01-01 00:00:00 ~ 9999-12-31 23:59:59,后者范围为 1970-01-01 08:00:01 到 2038-01-19 11:14:07 。所以 TIMESTAMP 支持的范围比 DATATIME 要小。
2) timestamp可以在insert/update行时,自动更新时间字段(如 f_set_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP),但一个表只能有一个这样的定义。
3) timestamp显示与时区有关,内部总是以 UTC 毫秒 来存的。还受到严格模式的限制
4) 优先使用timestamp,datetime也没问题
5) where条件里不要对时间列上使用时间函数
4.建议字段都定义为NOT NULL
1) 如果是索引字段,一定要定义为not null 。因为null值会影响cordinate统计,影响优化器对索引的选择
2) 如果不能保证insert时一定有值过来,定义时使用default ‘’ ,或 0
5.同一意义的字段定义必须相同
比如不同表中都有 f_user_id 字段,那么它的类型、字段长度要设计成一样