数据库命令规范
- 所有数据库对象必须使用小写字母并是用下划线分割
- 所有数据库对象名称禁止使用MySQL的保留关键字(否则查询时需要将其用单引号括起来)
- 数据库对象的命名要清晰
- 临时表必须以tmp_为前缀并以日期为后缀,备份表必须以bak_为前缀并以日期为后缀
- 所有存储相同数据的列名和类型必须一致,因为作为关联列,不一致可能会造成索引失效
数据库基本设计规范
- 所有表必须使用Innodb存储引擎
- 数据库和表的字符集统一使用UTF8,emoji表情需要使用utf8mb4字符集
- 所有表和字段都需要注释
- 尽量控制单表数据量大小,建议500万以内
- 谨慎使用MySQL分区表
- 尽量做到冷热数据分离,减小表的宽度,以充分利用MySQL的内存缓冲池
- 禁止在表中建立预留字段
- 禁止在数据库中存储图片,文件等大的二进制文件
数据库字段设计规范
-
优先选择符合存储需要的最小的数据类型,具体,将IP地址转换成整形数据,对于非负型的数据,优先使用无符号整型来存储,对于非负数据,优先使用无符号整型来存储
-
避免使用TEXT,BLOB数据类型,最常见的TEXT类型可以存储64k的数据,如果要用,建议把BLOB或TEXT列分离到单独的扩展表中。因为MySQL内存临时表不支持TEXT,BLOB这样的大数据类型,如果查询中包含这样的数据,在排序等操作时,就不能使用内存临时表,必须使用磁盘临时表。
-
避免使用ENUM类型,因为枚举类型order by效率低
-
尽可能把所有列定义为NOT NULL,索引NULL需要额外的空间来保存,所以占用更多的空间。
-
使用TIMESTAMP或DATETIME来存储时间
-
同财务相关的金额类数据必须使用decimal类型
索引设计规范
-
限制每张表的上的索引数量,建议单张表索引不超过5个
-
禁止给表中的每一列都建立单独的索引
-
每个Innodb表必须有个主键,Innodb如果没有设置主键,那么就会有第一个唯一索引作为主键,如果还没有,就会自动生成一个不可见的row_id作为主键。表是按照主键索引的顺序来组织,所以不要使用UUID等非递增的主键(会不断重新调整页,俗称页分裂),不要使用更新频繁的列作为主键(意味着要重新调整页)。
-
常见索引列建议,出现在SELECT、UPDATE、DELETE语句的WHERE从句中的列,包含在ORDER BY、GROUP BY、DISTINCT中的字段,多表join的关联列。
-
选择性高的放在最左侧,字段长度小的列放在联合索引的最左侧,使用最频繁的列放在联合索引的左侧。
-
避免冗余索引和重复索引,增加了查询优化器生成执行计划的时间
-
避免使用数据库外键约束,应该由程序控制,原因:1.每次修改数据,数据库都要去检查另一个表的数据,获取额外的锁,容易死锁。2.性能问题,每次插入数据都需要判断另一张是否存在数据,由程序控制可以省略一些判断。3.扩展性问题,分库分表方便,更换数据库方便,比如从Mysql到Oracle。4.技术问题,DBA往往小公司都没有,减少数据库性能问题,极为重要。
数据库SQL开发规范
-
使用预编译语句进行数据库操作
-
避免数据类型的隐式转换,比如
select name,phone from customer wehre id = '111'; 这个语句从字符串转换为数字的话,索引会失效的
-
充分利用表上已经存在的索引
-
禁止使用SELECT * 必须使用 SELECT 字段列表查询,
-
禁止使用不含字段列表的INSERT语句
-
避免使用子查询,可以把子查询优化为join操作,通常子查询在in子句中,且子查询中为简单SQL时,才可以把子查询转化为关联查询进行优化。子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响。子查询产生大量的临时表也没有索引,所以会消耗过多的CPU和IO资源,产生大量慢查询。
-
避免使用JOIN关联太多的表,MySQL是存在关联缓存的,缓存的大小可以由join_buffer_size参数进行设置。如果join_buffer_size设置不合理,就会造成服务器内存溢出,影响服务器数据库性能的稳定性。一般不建议超过5个。
-
减少同数据库的交互次数
-
对应同一列进行or判断时,使用in代替or,or大多数不能利用索引
-
WHERE从句中禁止对列进行函数转换和计算
-
在明显不会重复是使用UNION ALL而不是UNION,因为UNION有一个去重操作。
-
拆分复杂的大SQL为多个小SQL
数据库操作行为规范
- 超100万行的批量写操作,要分批次进行,大批量引起严重的主从延迟,binlog日志为row格式时会产生大量日志,避免大事务操作,大事务会造成表中大批量数据进行锁定,从而导致大量阻塞,阻塞会对MySQL的性能产生非常大的影响,长时间的阻塞,会占满数据库所有的可用连接。
- 对于大表使用pt-online-schema-change修改表结构,原理是新建一个与原结构相同的新表,然后复制。