一、数据库命令规范
所有数据库对象名称必须使用小写字母并用下划线分割
所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来)
数据库对象的命名要能做到见名识意,并且最后不要超过32个字符
临时库表必须以tmp_为前缀并以日期为后缀,备份表必须以bak_为前缀并以日期(时间戳)为后缀
所有存储相同数据的列名和列类型必须一致(一般作为关联列,如果查询时关联列类型不一致会自动进行数据类型隐式转换,会造成列上的索引失效,导致查询效率降低)
二、数据库基本设计规范
1、所有表必须使用Innodb存储引擎
三、数据库字段设计规范
1、优先选择符合存储需要的最小的数据类型
原因
列的字段越大,建立索引时所需要的空间也就越大,这样一页中所能存储的索引节点的数量也就越少也越少,在遍历时所需要的IO次数也就越多, 索引的性能也就越差
方法
如果一定要使用,建议把BLOB或是TEXT列分离到单独的扩展表中,查询时一定不要使用select * 而只需要取出必要的列,不需要TEXT列的数据时不要对该列进行查询。
TEXT或BLOB类型只能使用前缀索引
3、避免使用ENUM类型
修改ENUM值需要使用ALTER语句
ENUM类型的ORDER BY操作效率低,需要额外操作
禁止使用数值作为ENUM的枚举值
原因:
索引列需要额外的空间来保存,所以要占用更多的空间;
进行比较和计算时要对值做特别的处理
经常会有人用字符串存储日期型的数据(不正确的做法):
缺点1:无法用日期函数进行计算和比较
缺点2:用字符串存储日期要占用更多的空间
6、同财务相关的金额类数据必须使用decimal类型
非精准浮点:float,double
精准浮点:decimal
四、索引设计规范
1、限制每张表上的索引数量,建议单张表索引不超过5个
五、常见索引列建议
出现在SELECT、UPDATE、DELETE语句的WHERE从句中的列
包含在ORDER BY、GROUP BY、DISTINCT中的字段
并不要将符合1和2中的字段的列都建立一个索引,通常将1、2中的字段建立联合索引效果更好
多表join的关联列
六、如何选择索引列的顺序
建立索引的目的是:希望通过索引进行数据查找,减少随机IO,增加查询性能 ,索引能过滤出越少的数据,则从磁盘中读入的数据也就越少。
区分度最高的放在联合索引的最左侧(区分度=列中不同值的数量/列的总行数);
尽量把字段长度小的列放在联合索引的最左侧(因为字段长度越小,一页能存储的数据量越大,IO性能也就越好);
使用最频繁的列放到联合索引的左侧(这样可以比较少的建立一些索引)。
七、避免建立冗余索引和重复索引
因为这样会增加查询优化器生成执行计划的时间。
重复索引示例:primary key(id)、index(id)、unique index(id)
冗余索引示例:index(a,b,c)、index(a,b)、index(a)
八、优先考虑覆盖索引
对于频繁的查询优先考虑使用覆盖索引。
如果是用二级索引查询数据的话,在查找到相应的键值后,还要通过主键进行二次查询才能获取我们真实所需要的数据。而在覆盖索引中,二级索引的键值中可以获取所有的数据,避免了对主键的二次查询 ,减少了IO操作,提升了查询效率。
可以把随机IO变成顺序IO加快查询效率
九、索引SET规范
尽量避免使用外键约束
不建议使用外键约束(foreign key),但一定要在表与表之间的关联键上建立索引;
外键可用于保证数据的参照完整性,但建议在业务端实现;
外键会影响父表和子表的写操作从而降低性能。
十、数据库SQL开发规范
1、建议使用预编译语句进行数据库操作
3、充分利用表上已经存在的索引
避免使用双%号的查询条件。
如a like %123%,(如果无前置%,只有后置%,是可以用到列上的索引的)
一个SQL只能利用到复合索引中的一列进行范围查询
如:有 a,b,c列的联合索引,在查询条件中有a列的范围查询,则在b,c列上的索引将不会被用到,在定义联合索引时,如果a列要用到范围查找的话,就要把a列放到联合索引的右侧。
使用left join或 not exists来优化not in操作
5、程序连接不同的数据库使用不同的账号,进制跨库查询
为数据库迁移和分库分表留出余
降低业务耦合度
避免权限过大而产生的安全风险
原因:
消耗更多的CPU和IO以网络带宽资源
无法使用覆盖索引
可减少表结构变更带来的影响
子查询性能差的原因:
子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响;
特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大;
由于子查询会产生大量的临时表也没有索引,所以会消耗过多的CPU和IO资源,产生大量的慢查询。
对列进行函数转换或计算时会导致无法使用索引。
不推荐:
where date(create_time)=20190101
推荐:
14、在明显不会有重复值时使用UNION ALL而不是UNION
UNION会把两个结果集的所有数据放到临时表中后再进行去重操
UNION ALL不会再对结果集进行去重操作
15、拆分复杂的大SQL为多个小SQL
大SQL:逻辑上比较复杂,需要占用大量CPU进行计算的SQL
MySQL:一个SQL只能使用一个CPU进行计算
SQL拆分后可以通过并行执行来提高处理效率
十一、数据库操作行为规范
1、超100万行的批量写(UPDATE、DELETE、INSERT)操作,要分批多次进行操作
大批量操作可能会造成严重的主从延迟
主从环境中,大批量操作可能会造成严重的主从延迟,大批量的写操作一般都需要执行一定长的时间,而只有当主库上执行完成后,才会在其他从库上执行,所以会造成主库与从库长时间的延迟情况
binlog日志为row格式时会产生大量的日志
大批量写操作会产生大量日志,特别是对于row格式二进制数据而言,由于在row格式中会记录每一行数据的修改,我们一次修改的数据越多,产生的日志量也就会越多,日志的传输和恢复所需要的时间也就越长,这也是造成主从延迟的一个原因。
避免产生大事务操作
2、对于大表使用pt-online-schema-change修改表结构
避免大表修改产生的主从延
避免在对表字段进行修改时进行锁表
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/6540/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料