良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询语句来设计schema,这往往需要权衡各种因素。
比如反范式的设计可以加快某些类型的查询,但同时可能使另一些类型的查询变慢。
比如添加计数表和汇总表是一种很好的优化查询的方式,但这些表的维护成本可能会很高。 MySQL独有的特性和实现细节对性能的影响也很大。
选择优化的数据库类型



datetime和 timestamp 的区别 https://www.cnblogs.com/xuliuzai/p/10901425.html
整型类型


实数类型
是带有小数的数字
**
FL0AT和 DOUBLE类型支持使用标准的浮点运算进行近似计算。
DECIMAL类型用于存储精确的小数。DECIMAL类型支持精确计算。
因为CPU不支持对 DECIMAL的直接计算,所以在 MySQL50以及更高版本中, MySQL服务器自身实现了 DECIMAL的髙精度计算。相对而言,CPU直接支持原生浮点计算,所以浮点运算明显更快。
浮点和 DECIMAL类型都可以指定精度。
https://gitee.com/meader/sharefiles/raw/master/uPic/20210703-183657-0288.png
建议只指定数据类型,不指定精度。
float 使用4个字节 ,double使用8个字节;
字符串类型
varchar




char

示例:
https://gitee.com/meader/sharefiles/raw/master/uPic/20210703-193619-0901.png
https://gitee.com/meader/sharefiles/raw/master/uPic/20210703-195819-0000.png

Blog 和 Text 类型
BL0B和TEXT都是为存储很大的数据而设计的字符串数据类型,分别采用二进制和字符方式存储。
当BL0B和TEXT值太大时, InnodB会使用专门的“外部”存储区域来进行存储,此时每个值在行内需要1~4个字节存储一个指针,然后在外部
存储区域存储实际的值。
BL0B和TEXT家族之间仅有的不同是BL0B类型存储的是二进制数据,没有排序规则或字符集,而TEXT类型有字符集和排序规则。
BL0B和TEXT只对每列的最前max_sort_length字节排序。可以减小max_sort_length的配置,**或者使用ORDER BY SUSTRING( column, length)。
使用枚举(ENUM)代替字符串类型
在实际中很少应用。
可以使用枚举列代替常用的字符串类型。
枚举最不好的地方是,字符串列表是固定的,添加或删除字符串必须使用 ALTER TABLE。
日期和时间类型
datetime使用8个字节存储空间,与时区无关
timestamp使用4个字节存储空间,自动定位时区,插入数据时没有指定值,自动填充当前时间(可配置这种行为),
比秒更小粒度的日期和时间值 mysql还没有提供,但是可以使用bigint类型存储时间戳。
位数据类型
(很少使用,不做解释)
选择标识符
为标识列( identifier column)选择合适的数据类型非常重要
当选择标识列的类型时,不仅仅需要考虑存储类型,还需要考虑 MySQL对这种类型怎么执行计算和比较。
如果可能,应该避免使用字符串类型作为标识列,因为它们很消耗空间,通常比数字类型慢。
如果存储UUID值,则应该移除“-”符号;或者更好的做法是,用 UNHEX()函数转换UUID值为16字节的数字,并且存储在一个 BINARY(16)列中。检索时可以通过HEX()函数来格式化为十六进制格式。
特殊类型数据
IPv4地址。人们经常使用 VARCHAR(15)列来存储IP地址。然而,它们实际上是32位无符号整数,不是字符串。用小数点将地址分成四段的表示方法只是
为了让人们阅读容易。所以应该用无符号整数存储IP地址。 MySQL提供 INET ATON()和 INET NT0A()函数在这两种表示方法之间转换。
MySQL schema设计中的陷阱





范式和反范式
范式的优点:
缺点:
需要表关联
混用范式化和反范式化
完全的范式化和完全的反范式化 schema都是实验室里才有的东西:在真实世界中很少会这么极端地使用。在实际应用中经常需要混用,可能使用部分范式化的schema、缓存表,以及其他技巧。
缓存表和汇总表
有时提升性能最好的方法是在同一张表中保存衍生的冗余数据。然而,有时也需要创建张完全独立的汇总表或缓存表(特别是为满足检索的需求时)。如果能容许少量的脏数据,这是非常好的方法,但是有时确实没有选择的余地(例如,需要避免复杂、昂贵的实时更新操作)。
物化视图
物化视图实际上是预先计算并且存储在磁盘上的表,可以通过各种各样的策略刷新和更新。 MySQL并不原生支持物化视图。
计数器表
如果应用在表中保存计数器,则在更新计数器时可能碰到并发问题。计数器表在Web应用中很常见。可以用这种表缓存一个用户的朋友数、文件下载次数等。创建一张独立的表存储计数器通常是个好主意,这样可使计数器表小且快。使用独立的表可以帮助避免查询缓存失效,并且可以使用本节展示的一些更高级的技巧。
加快 ALTER TABLE操作的速度
MySQL的 ALTER TABLE操作的性能对大表来说是个大问题。 MySQL执行大部分修改表结构操作的方法是用新的结构创建一个空表,从旧表中查出所有数据插入新表,然后删除旧表。

不是所有的 ALTER TABLE操作都会引起表重建。例如,有两种方法可以改变或者删除个列的默认值(一种方法很快,另外一种则很慢)。
第一种:
第二种:
只修改.frm文件
从上面的例子我们看到修改表的m文件是很快的,但 MySQL有时候会在没有必要的时候也重建表。如果愿意冒一些风险,可以让 My SQL做一些其他类型的修改而不用重建表。

快速创建 MyISAM索引
为了高效地载入数据到 MyISAM表中,有一个常用的技巧是先禁用索引、载入数据,然后重新启用索引。

也可以使用像前面说的 ALTER TABLE的骇客方法来加速这个操作,但需要多做一些工作并且承担一定的风险。这对从备份中载入数据是很有用的,例如,当已经知道所有数据都是有效的并且没有必要做唯一性检查时就可以这么来操作。
操作步骤:
<不太懂>
总结


