首先是数据类型选择的总的逻辑
1,通常情况下越小越好--节省空间
2,通常情况越简单越好--节省算力,整型的计算量显然小于char,更别提其他类型
3,避免NULL--1)被索引时多用一个字节;2)索引,比较计算时更复杂;3)被索引时更难优化;4)业务写入数据时,如果忘写这个值,也不会报错(置为null了)
一,整数类型
TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT.分别使用8,16,24,32,64为存储空间,通常来说TINYINT,INT,BIGINT使用的比较多
INT(10)和INT(20)没有本质区别,只影响显示,这恰恰是业务最容易忽略的地方,很多人一致认为数字代表长度,甚至使用INT(1)来存储0/1
二,实数类型
实数就是有小数点的数字
一般来说主要有decimal,float,double三种
decimal(A,B)表示数字有A个数字,其中有B个是小数,主要特点是精确控制小数位数;就业务而言,金融/财经常常会用到,因为需要控制精确度。
实质上 decimal 是double类型
float和double都是浮点数类型,单精度双精度很清楚,其中float占4个字节,那么doule显然就占8个字节了;就业务使用而言,尽可能用double,虽然float比较省空间,但就使用场景而言,既然选择使用浮点型,那么就是对数据的准确性要求比较高的场景,建议使用精度更高的double。在现在的场景下,磁盘空间不是瓶颈,ssd价格也不贵。核心业务多付出总不会错
三,字符串类型
字符串主要分为char和varchar两种类型;遇事不决,就选varchar,可能不合理,但这就是现实,
varchar比char多个1个字节(大于255时,多两个字节)用于存储长度信息
varchar的问题在于,如果增加varchar存储数据的长度时,可能涉及页分裂,产生碎片;从生产环境看,我几乎没有见过char类型,可能原因是业务自己也弄不清楚这个字段长度是不是要变吧,他们不会在乎多用了字节(事实上我也不在乎),总之无脑使用varchar至少不会太差,总比使用char后改表,改代码来的方便。
四,BLOB和TEXT类型
这两者都用存储很大的数据,区别是BLOB使用二进制存储,TEXT使用字符存储
当这两个太大时,innodb会使用外部空间存储,索引表上的数据实际为指针,由于公司的建表提案硬性要求每个字段都必须是not null defalut ,让我深深的记住了,text类型不能设置default值,因为得手动建/改表
BLOB和TEXT类型都不能设置默认值,没有找到准确的原因,大概是由于一个兼容性问题。可以通过禁用严格模式来接触限制(修改sql mode),但是极其不建议;我很懒。但是从没有想过解除严格默认,而是老老实实的手动操作
五,枚举ENUM
枚举类型适合存储固定的选项的字符串,比如性别,只有两个选项,有点是数据存储占用小,这可能就是唯一的优势了,可惜业务不在乎
缺点是,由于字符串列表是固定的,修改时需要alter table,这是个代价比较高的操作;实际情况时,生产环境中,唯一不变的就是什么都有可能改变,即使是性别,未来我相信也会不只两个选项,所以不推荐业务使用
此外 枚举类型实质上存储的是数字(这也是占用空间小的原因),内部排序也是按照数字排序的;这可能是个坑,隔壁部门做数据分析,结果枚举类型采集的是数字,导致业务部门搜索不到数据(敏感数据,很重要)
六,时间和日期
主要是datatime和timestamp两种,
datatime使用8个字节,能表示的时间范围很大(肯定够用),与时区无关
timestamp 使用4个字节,时间范围小(1970~2038,不远的将来),与时区相关,两者的精度都是s
一般来说使用timestamp因为节省空间;在较新的mysql版本中,sqlmode会默认不许时间类型字段值为全0,需要注意,一般建议业务将默认值设置为1970-10-10 10:00:00,个人习惯。没有特殊情况(比如对group by的限制),不修改sqlmode
以上覆盖的99%的场景,绝大多是都是整数和varchar就能覆盖。
















