《高性能MySQL》之Schema与数据类型优化

ppgo8 于 2023-02-28 发布

Schema与数据类型优化

​ 《高性能MySQL》第4章 MySQL基准测试读书笔记

​ 本章为接下来的两个章节做铺垫。在这三章中,将讨论逻辑设计、物理设计和查询执行,以及它们之间的关系。再阅读完索引和查询优化的章节后,再回来看这一张,会发现本章很有用。

选择优化的数据类型

​ 下面的几个原则可能有助于选择合适的数据类型。

​ 在选择数据类型时,首先选择大数据类型:数字、字符串、时间等。然后选择具体的类型。MySQL可以存储相同类型的数据,只是存储的长度和范围不同、允许的精度不同,相同大类型的子类型也有一些特殊的行为和属性。

整数类型

​ 数字类型:整数和实数。

整数类型:

各个类型的存储范围是,$-2^{(n-1)}$到$2^{n-1}-1$,其中$n$是存储空间的位数。

整数类型还有可选的unsigned属性,表示不允许负值,这大致可以使正数的上限提高一倍

实数类型

字符串类型

​ 数据如何存储取决于存储引擎,并非所有的存储引擎都会按照相同的方式处理定长或变长的字符串。Mermory只支持定长的行,即使有变长字段也会根据最大长度分配空间不过,填充和截取空格的行为在不同的存储引擎是一样的,因为这是在MySQL服务器层处理的

日期和时间类型

​ MySQL能存储的最小时间力度为秒(MariaDB支持微秒级别的时间类型),但是MySQL也可以使用微秒级别的粒度进行临时运算。

位数据类型

选择标识符

标识符:(主键)标识列用的。最好是整数类型。

特殊类型数据

范式和反范式

在范式的数据库中,每个事实数据会出现并且只出现一次

在反范式化的数据库中,信息是冗余的,可能会存储在多个地方

范式优缺点

优点

缺点

反范式的优点和缺点

优点

混用范式化和反范式化

​ 怎么选择最佳的设计?

​ 完全的范式化或反范式化schema是实验室才有的东西,真实世界不会这么极端,在显示世界经常会混用。

​ 常见的反范式化数据:

缓存表和汇总表

​ 有时提升性能最好的方法是在同一张表中保存衍生的冗余数据

​ 这两个表并没有标准的定义。

​ 缓存表:存储从schema其他表(但是获取速度较慢)获取数据的表。(例如,数据逻辑上是冗余的)

​ 汇总表:存储使用group by语句聚合数据的表。(例如,数据逻辑上不是冗余的)

物化视图

​ 物化视图:预先计算并且存储在磁盘上的表,可以通过各种各样的粗略的刷新和更新

​ MySQL并不原生支持物化视图。开源工具Flexviews可以自己实现物化视图,它由下面的几个功能:

计数器表

​ 应用在表中的计数器,在更新计数器时可能会碰到并发问题。计数器表在Web的应用中很常见。建议创建一张独立的表存储计数器,优点:计数器表小且块;避免查询缓存失效。

启发:表+操作(sum)共同完成了需求,而不是只在表的设计中,

​ 如果希望减少表的行数,以免表变得太大,可以写一个周期执行的任务,合并所有结果到0号槽,并删除所有其他的槽。

image-20230302100839122

image-20230302100925378

加快alter table操作的速度

​ alter table的方法是痛苦的,因为大多数情况下,它都会锁表并且重建整张表。下面展示一些特殊场景可以使用的骇客方法。

​ MySQL执行大部分修改表结构的方法是:用新的结构创建一个空表,从旧表中查出所有数据插入新表,然后删除旧表。这样的操作会花费很长时间。

​ 如有要修改默认值,两个操作

只修改.frm文件

​ 以下操作有风险,不受官方支持,也没有文档记录。执行之前要首先备份数据1

下面这些操作有可能是不需要重建表的:

​ 基本的技术是为想要的表结构创建一个新的.frm文件,然后用它替换掉那张已经存在的.frm文件,具体操作如下:

image-20230302102624129

快速创建MyISAM索引

总结

​ 尽可能保持任何东西小而简单总是好的,一些设计、使用schema原则如下:

​ 范式是好的,但是反范式有时也去必须的,有时能带来极大的好处。预先计算、缓存或生成汇总表可能获得很大的好处,