一、数据类型优化
整体原则:
1.小的通常更好:在满足需求的前提下,尽量选择占用存储空间小的类型
2.简单就好:简单数据类型往往只需要更短的CPU周期,同时也可以减小数据库在运算时的压力
3.尽量避免使用NULL,尤其是有索引的情况下
数值类型
1.整数类型
在mysql中,整数类型一共分为五种,分别是tinyint(8)、smallint(16)、mediumint(24)、int(32)、bigint(64),括号里的数字为所占位数
整数类型还有一个unsigned关键值,所占位数和不加此关键字的位数一致,但是不包括负数,可根据实际情况自行决定是否使用。
整数类型可以指定长度,例如int(11),但是对于存储和运算来说,并没有任何的意义,这种写法并不会对数据的长度有限制,它只是规定了在一些交互工具中所显示的长度。
2.实数类型
对于实数来讲,需要搞清楚的是以下几点
double类型为mysql内部浮点计算的类型
decimal类型可以进行精确计算,但是在存储和运算的时候会产生额外的开销,因此除了极少数情况下,一般不用这种类型,如果要进行精确计算,可以将数据扩大一定倍数后用int或bigint来进行存储。
字符类型
char和varchar类型
char类型是最基本的字符类型,它是定长的,数据长度不够时用空格填充。
varchar类型是可变长度的,因为长度可变,所以它比char类型更节省空间,在检索的时候数据末尾的空格会被舍弃。同时,这种数据类型在进行update操作的时候要比char复杂一些,总的来说它的使用策略如下:
1.字符串列中的数据长度相差很多的情况,因为数据长短差异大,使用char会浪费大量的空间。
2.使用了复杂的字符集(utf-8)的时候也可以用varchar类型。
binary和varbinary类型
这两种类型与char和varchar类型很相似,只是它们存储的是二进制类型的字符串,数据长度不够时用 填充,在检索时不会去掉填充。
blob和text类型
这两种类型是为了存储很大的数据而设计的字符串数据类型,blob存储二进制,而text存储普通字符,因为这两种类型字段中的数据会很大,所以MySQL在排序的时候只对列最左边的max_sort_length个字符进行排序。
枚举类型
在某些特定的时候可以用枚举来代替字符串类型,MySQL在内部会将枚举中的每个值在列表中的位置保存为整数,并且在表的.frm文件中保存其映射关系。注意事项如下:
1.由于枚举在数据库中实际保存的是整数,所以我们不要把数值做为枚举的常量,这样容易造成混淆。
2.枚举中的字符串列表都是固定的,要更改只能使用alter table,因此,枚举中不要存放可变的字符串。
日期和时间类型
这个类型没什么可说的,主要就是根据实际情况选择自己所需要的类型。
位数据类型
bit类型:这种数据类型可以用来存储一个或多个true/false的值(最多64个),在MySQL中,bit被当作是是字符串类型,而不是数值类型,当检索bit(1)的值时,结果是一个包含二进制0或1的字符串,然而,在数字上下文的场景中检索时,结果将是位字符转换成数字。因此,虽然理论上bit可以保存多个布尔值,为了避免麻烦,尽量避免这种用法。
set类型:这种数据类型一般用来保存很多布尔值,它在MySQL内部是以一系列打包的位的集合来表示的。有效的利用了存储空间,在访问的时候可以用find_in_set()、field()之类的函数,方便查询使用。缺点也很明显,改变列的定义的代价较高,需要alter table,并且也无法在set列上通过索引查找。
其他
选择标识列:一般情况下,尽量使用整形来作为标识列,因为它是简单类型,运算简单而且可以使用auto_increment,如果实在无法使用整形,应该尽量选择比较其他类型简单且空间较小的类型,以便在select、insert等操作时能更加高效。
特殊类型数据:例如IP地址,人们会经常用varchar(15)来存储IP地址,但实际上IP地址是一个32位无符号的整数,而不是一个字符串,所以应该用无符号整数来存储IP地址,利用MySQL提供的INET_ATON()和INET_NTOA()来操作。
二、scheme优化
整体原则:
应避免一个表中有太多的列,如果列数太多,存储引擎将编码过的列转换成行数据结构的操作代价会非常高。
应避免联表太多,MySQL中最多允许联表数为61张,如果希望查询执行恰且并发性好,应该保证联表数控制在12张以内。
避免过度使用枚举
范式和反范式
范式:根据数据的依赖关系,尽可能的将数据分得细一些,存储在不同的表中,范式化后的表更新操作会比较快,冗余数据会很少,但查询的时候通常会要联很多表,常用的有第一、第二、第三范式。
反范式:将大量数据存放在一个表中,查询的时候不用联很多表,但做更新操作时会比较慢,数据会有大量的冗余。
计数器表:
存int字段的表,小且快;依旧可能存在互斥锁性能问题,可以用多条记录随机更新方案(我们公司https://www.22.cn数据量还没那么庞大,这个只是个思路~)