选择优化的数据类型

数据类型的选择原则

  • 更小的通常更好。一般情况下,应该尽量使用可以正确储存数据的最小数据类型。例如只需要存0~200,tinyint unsigned更好。
  • 简单就好。简单数据类型的操作通常需要更少的CPU周期。例如,整型字符串操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂。比如,应该使用MySQL内建的类型而不是字符串来存储日期和时间,另外一个是应该用整型存储IP地址。
  • 尽量避免NULL, 通常情况下最好指定列为not null, 除非真的需要存储null值。通常把null的列改为not null带来的性能提升比较小,所以调优时没有必要首先在现有schema中查找并修改掉这种情况,除非确定这会导致问题。但是,如果计划在列上建索引,就应该尽量避免设计成可为null的列。

MySQL支持别名,但它不会影响性能。

整型

分为整型和实数。如果储存整数。可以使用:tinyint、smallint、mediumint、int、bigint,分别使用8,16,24,32,64位存储空间,储存的值的范围从-2^(N-1)到2^(N-1)-1,其中N是存储空间的位数。

整型类型有可选的unsigned属性,表示不允许负号,这大致可以使正数的上限提高一倍。同时有符号和无符号类型(表示正负数)使用相同的储存空间,并具有相同的性能。

实数类型

实数是带有小数部分的数字。也可以使用decimal存储比bigint还大的整数。

浮点(float、double)和decimal类型都可以指定精度。浮点类型在存储同样范围的值时,通常比decimal使用更少的空间。因为需要额外的空间和计算开销,应该只在对小数进行精确计算时才使用decimal——例如存储财务数据。

字符串类型

varchar和char类型,下面的描述假设使用的存储引擎是InnoDB/MyISAM。

  • varchar类型用于存储可变长字符串。它比定长类型更节省空间,因为它仅使用必要的空间(例如,越短的字符串使用越少的空间)。 varchar的使用场景:字符串列的最大长度比平均长度大很多;列的更新很少;使用了像UTF-8这样复杂的字符集,每个字符都使用不同的字节数进行存储。
  • char类型是定长的:MySQL总是根据定义的字符串长度分配足够的空间。char类型使用场景:适合存储很短的字符串,或者所有值都接近同一个长度。比如:非常适合存储密码的MD5值,因为这是一个定长的值。储存经常变更的数据,char也比varchar更好,因为定长的char类型不容易产生碎片。对于非常短的列,char比varchar在存储空间上也更有效率,因为它不需要额外字节记录字符串的长度。例如用char(1)来存储只有Y和N的值。

最好的策略是只分配真正需要的空间。

Blob和text类型

Blob和text都是为了存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。

使用枚举(Enum)代替字符串类型

使用场景:
枚举列可以把一些不重复的字符串存储成一个预定义的集合并且除非能接受只在列表末尾添加元素,因为字符串列表是固定的,对于一系列未来可能会改变的字符串,使用枚举不是一个好主意。

优点:
enum关联enum后,关联查询变得更快。当varchar列和enum列进行关联时则慢很多。
把varchar列转换为enum可以让表的大小缩小,可以根据show table status命令输出结果中data_length列的值。

位数据类型

bit列,列在一列中存储一个或多个true/false值。对于大部分应用,最好避免使用这种类型,另一个方法是创建一个char(1),用来存储0/1。

set列,如果需要保存很多true/false值,可以考虑合并这些列到一个set数据类型,它在MySQL内部是以一些列打包的位的集合来表示的。建议set列中的情况会同时出现时使用。
这样有效地利用了存储空间。一个包装位的应用的例子是保存权限的访问控制列表(ACL)。

CREATE TABLE acl(
    perms SET('can_read','can_wrtie','can_delete') NOT NULL
);

INSERT INTO acl(perms) VALUES('can_read,can_delete');
SELECT perms FROM acl WHERE FIND_IN_SET('can_delete',perms);--查询字段perms中包含can_delete的结果,返回结果为null或记录

结果:
image.png


WinRT
24 声望4 粉丝

临渊羡鱼,不如退而结网