高性能MYSQL读书要点摘录_3_Schema与数据类型优化

一 选择优化的数据类型

  1.  更小的通常更好:占用更少的磁盘,内存 ,CPU。同时要确保没有低估要存储值的范围。

  2.  简单就好:简单的数据类型操作通常需要更少的CPU周期。比如 整形比字符操作的代价更低。

  3. 尽量避免NULL:通常情况下最好指定列为NOT NULL,除非真的要存储为NULL。因为如果查询中包含NULL的列,对MYSQL来说更难优化,因为可为NULL的列使得索引,索引统计和值比较都更加复杂。同时 可为NULL的列会使用更多的存储空间,在MYSQL里需要特殊处理。

  4. 为列确定合适的数据类型,第一步需要确定合适的大类型:数字,字符串,时间等;第二步,选择具体的类型。很多MYSQL的数据类型可以存储为相同的数据类型,只是存储的长度和范围不一样、允许的精度不同,相同大类型的不同子类型数据有时也有一些特殊的行为和属性。例如datetime和timestamp列都可以存储相同的类型的数据:时间和日期,精确到秒。然而timestamp只使用datetime一半的存储空间,并且会根据时区变化,具有特殊的自动更新能力。另一方面,TIMESTAMP允许的时间范围要小的多,有时候它的特殊能力会成为障碍。MYSQL为了兼容性支持很多别名,例如INTEGER,BOOL,NUMERIC都是整形,只是别名不同。通过show create table 可以查看基本类型,而不是别名。

二 整数类型

    整数类型包含:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT。分别使用8,16,24,32,64位存储空间。整数类型可选UNSIGNED属性,表示不允许负值,可以使得正数的上限提高一倍。有符号和无符号类型使用相同的存储空间,并且有相同的性能,因此可以根据实际情况选择合适的类型。

    MYSQL可以为整数类型指定宽度,例如INT(11),对大多数应用没有意义的:它不会限制值的合法范围,只是规定了MYSQL的一些交互工具(例如MYSQL命令行客户端)用来显示字符的个数。对于存储和计算来说,INT(1)和INT(20)是相同的。


三 实数类型

    MySQL即支持精确的类型,也支持不精确的类型。FLOAT和DOUBLE支持标准的浮点运算进行近似计算。DECIMAL类型用于存储精确的小数。

    浮点类型和DECIMAL类型都可以指定精度。对于DECIMAL列,可以指定小数点前后所允许的最大位数。这会影响列的空间消耗。例如,DECIMAL(18,9)小数点的两边将各存储9个数字,一共使用9个字节:小数点前的数字用4个字节,小数点后的数字用4个字节,小数点本身占一个字节。


四 字符串类型

    VARCHAR和CHAR类型是两种最主要的字符串类型。VARCHAR类型用于存储可变长字符串,它比定长类型更加省空间,因为它仅使用必要的空间。VARCHAR需要使用1或2个额外字节记录字符串的长度。CHAR适合存储很短的字符串,或者所有值长度接近的。例如 CHAR非常适合存储密码的MD5值。

    与CHAR和VARCHAR类似的类型还有BINARY和VARBINARY,它们存储的是二进制字符串。二进制字符串存储的是字节码而不是字符。二进制存储相对于字符存储有比较方面的优势,按字节比较速度更快。

    BLOB和TEXT类型都是为了存储很大的数据而设计的字符串类型,分别采用二进制和字符方式存储。BLOB存储的是二进制数据,没有排序规则或字符集,而TEXT类型有字符集和排序的规则。同时 MYSQL不能将BLOB和TEXT列全部长度的字符串进行索引,也不能使用这些索引消除排序。

    使用枚举代替字符串类型,MYSQL会根据对应的关系 保存枚举类型的整形数值。

CREATE TABLE ENUM_TEST(e ENUM('fish','apple','dog') not null);
INSERT INTO ENUM_TEST(e) VALUES('fish'),('dog'),('apple');
--- 通过下面查询可以看到MYSQL实际存储的数值----

select e+0 from enum_test;

----如果想指定枚举查询的排序可以通过field()实现---
select e from enum_test order by field(e,'apple','dog','fish');


五 日期和时间类型

    DATETIME: 保存的范围较大,从1001年到9999年,精度为秒。使用8个字节的存储空间。

    TIMESTAMP:存储从1970年1月1日午夜开始的秒数,和unix时间戳类型。使用4个字节的存储空间 只能到2038年。

MYSQL提供了FROM_UNIXTIME()和UNIX_TIMESTAMP()函数实现日期和UNIX时间戳的相互转换。


六 其他类型

    位数据类型:BIT ,SET; 

    特殊数据类型比如存储IPv4时要把它存储为整形 ,可以通过mysql的inet_aton() 和inet_ntoa()函数实现IP字符形式和整数形式的转换。


七 schema设计中的陷阱

  1. 太多的列:MYSQL服务器层和存储引擎层之间通过行缓冲格式拷贝数据。如果列数太多,列转成行数据结构代价也会高。

  2. 太多的关联:单个查询最好在12个表以内做关联。

  3. 全能的枚举:防止过度使用枚举。

  4. 变相的枚举:ENUM列允许存储单个枚举值,集合(SET)允许存储一个或多个值。有时在这两个类型的选择容易混淆。

  5. NULL:可以通过使用0,或特殊值或空字符串代替NULL。

八 范式和反范式

    1 范式的优点和缺点:范式化的更新操作通常比反范式化要快;数据范式化好时,通常很少或者没有重复数据,所以修改更快;范式化的表通常更小,可以更好的放在内存里,所以执行操作会更快;范式化的缺点是通常需要更多的关联操作,同时可能会使一些索引策略无效;

    2 反范式化的优点和缺点:可以更好的避免关联操作,有效的使用索引策略;缺点是需要额外的存储空间。

    3 设计表结构时可以混用范式化和反范式化。

九 表结构设计其他技巧

  1. 使用缓存表和汇总表。。。。。。。。。


本文链接:http://my.oschina.net/robinyao/blog/596561

        

你可能感兴趣的:(mysql,schema,数据类型,高性能)