四、Schema与数据类型优化

发布时间 2023-07-28 20:13:57作者: LHX2018

4.1 选择优化的数据类型

更小的通常更好

一般情况下,应该尽量使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,因为它们占用更少的磁盘、内存和CPU缓存,并且处理时需要的CPU周期也更少。

但要确保没有低估需要存储的值的范围,因为在schema中的多个地方增加数据类型的范围是一个非常耗时和痛苦的操作。如果无法确定哪个数据类型是最好的,就选择你认为不会超过范围的最小类型。

简单越好

简单数据类型的操作通常需要更少的CPU周期。例如,整型比字符串操作代价更低,因为字符集和校对规则(排序规则)使字符比较比整型比较更复杂。(使用MySQL定好的时间类型而不是字符串存储时间,用整型存储IP地址)

尽量避免NULL

查询中包含可为NULL的列,对MySQL来说更难优化。可为NULL的列使得索引、索引统计和值比较都更复杂。可为NULL的列会使用更多的存储空间,在MySQL里需要特殊处理。当可为NULL的列被索引时,每个索引记录需要一个额外的字节。

可以用一个特殊值来替代NULL值。但遵循这个原则也不要走极端。

1)整数类型

有符号和无符号类型使用相同的存储空间,并具有相同的性能,因此可以根据实际情况选择合适的类型。

2)VARCHAR

比定长更节省空间,因为它仅使用必要的空间。VARCHAR需要还有1 或 2 个额外字节记录字符串的长度:如果列的最大长度小于或等于255字节,则只使用 1个字节表示,否则使用 2个字节。

3)CHAR

根据需要采用空格进行填充以方便比较

4)日期和时间类型

MySQL能存储的最小时间粒度为秒

DATETIME

这个类型能保存大范围的值,从10001年到9999年,精度为秒。它把日期和时间封装到格式为YYYYMMDDHHMMSS 的整数中,与时区无关。使用8个字节的存储空间。

默认情况下,MySQL以一种可排序的、无歧义的格式显示DATETIME值,例如 "2023-07-20 22:49:00"。这是 ANSI 标准定义的日期和时间表示方法。

TIMESTAMP

保存从 1970年1月1日以来的秒数,它和UNIX时间戳相同。TIMESTAMP只使用4个字节的存储空间,因此它的范围比DATETIME小的多,只能表示从1970年到2038年。


如果要存储更小粒度的日期和时间值怎么办?可以使用自己的存储格式,可以使用BIGINT存储微秒级别的时间戳。

4.6 总结

良好的schema设计原则是普遍适用的,但MySQL有它自己的实现细节要注意。概括来说,尽可能保持任何东西小而简单总是好的。MySQL喜欢简单,需要使用数据库的人应该也同样会喜欢简单的原则:

  • 尽量避免过度设计
  • 使用小而简单的合适数据类型,除非真实数据模型中有确切的需要,否则应该尽可能地避免使用NULL值
  • 尽量使用相同的数据类型存储相似或相关的值,尤其是要在关联条件中使用的列
  • 注意可变长字符串,其在临时表和排序时可能导致悲观的按最长长度分配内存
  • 尽量使用整型定义标识列
  • 避免使用MySQL已经遗弃的特性,例如指定浮点数的精度,或者整数的显示宽度
  • 小心使用ENUM和SET。虽然它们用起来很方便,但是不要滥用,否则有时候会变成陷阱。最好避免使用BIT

范式是好的,但是反范式(大多数情况下意味着重复数据)有时也是必需的,并且能带来好处

最后,ALTER TABLE是让人痛苦的操作,因为在大部分情况下,它都会锁表并且重建整张表