高性能MySQL笔记之数据类型和scheme优化

1、数据类型优化
总体原则:
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类型很类似,只是它们存储的是二进制类型的字符串,数据长度不够时用\0填充,在检索时不会去掉填充。
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()来操做。

2、scheme优化
总体原则:
应避免一个表中有太多的列,若是列数太多,存储引擎将编码过的列转换成行数据结构的操做代价会很是高。
应避免联表太多,MySQL中最多容许联表数为61张,若是但愿查询执行恰且并发性好,应该保证联表数控制在12张之内。
避免过分使用枚举
范式和反范式
范式:根据数据的依赖关系,尽量的将数据分得细一些,存储在不一样的表中,范式化后的表更新操做会比较快,冗余数据会不多,但查询的时候一般会要联不少表,经常使用的有第1、第2、第三范式。
反范式:将大量数据存放在一个表中,查询的时候不用联不少表,但作更新操做时会比较慢,数据会有大量的冗余。