• 沒有找到結果。

20.1.1 库表规约

● (强制)所有创建的MySQL表必须为InnoDB引擎。

● (强制)小数类型为decimal,禁止使用float和double。

● (强制)禁用保留字,如desc、range、match、delayed等,请参考MySQL官方 保留字。

● (强制)表必须有主键,可以使用业务相关,有序且具有唯一性的字段作为主 键,也可以使用业务无关的自增长字段作为主键。

● (强制)表字段必须有默认值+ NOT NULL,int等,数字类型默认值推荐给0,

varchar等字符类型默认值推荐给''。

● (推荐)不建议使用分区表,如有需要,可以使用多个独立的表代替。

● (推荐)建议表包含两个字段:create_time,update_time, 且均为datetime类 型。

● (推荐)单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。

● (推荐)varchar是可变长字符串,不预先分配存储空间,长度不要超过2048。如 果存储长度大于此值,定义字段类型为text,或者独立出来一张表,用主键来对 应,避免影响其他字段索引效率。

● (推荐)表单行行内长度不得超过1024字节,单表数据量控制在500万行以内。

● (推荐)控制单表字段数量,字段上限50左右。

● (推荐)如果存储的字符串长度几乎相等,使用char定长字符串类型。

● (推荐)字段允许适当跨表冗余,以避免关联查询,提高查询性能,但必须考虑 数据一致。

说明

冗余字段应遵循:

● 不是频繁修改的字段。

● 不是varchar超长字段,更不能是text字段。

● (参考)合适的存储长度(不建议使用LONG TEXT, BLOB等长类型字段),不但 节约数据库表空间、节约索引存储,更重要的是提升检索速度。

20.1.2 索引规约

● (强制)防止因为字段类型不同造成的隐式转换,导致索引失效。

● (推荐)业务上具有唯一特性的字段,即使是多个字段的组合,最好在所有具有 唯一特性字段的最小集合上建立唯一索引。例如:一个表含有有a,b,c,d,e,

f字段,在业务上ab和ef分别是具有唯一特性的字段集合,那么最好在最小集合ab 和ef上分别建立唯一索引。

● (推荐)尽量在定长的字段(如:INT)上建立索引;在varchar字段上建立索引 时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索 引长度即可。

● (推荐)页面搜索避免左模糊(如:SELECT * FROM users WHERE u_name LIKE

‘%hk’)或者全模糊,避免从索引扫描退化为全表扫描,如果需要请在应用层 解决。

● (推荐)如果有order by的场景,请注意利用索引的有序性。order by 最后的字 段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情 况,影响查询性能。

● (推荐)利用覆盖索引来进行查询操作,避免回表,但是覆盖索引加的字段不能 太多,要兼顾性能。

● (推荐)SQL性能优化的目标:至少要达到range级别,要求是ref级别,如果可以 是consts最好。

● (推荐)建组合索引的时候,区分度最高的在左边。

● (强制)禁止使用触发器,事件调度器(event scheduler)和视图实现业务逻 辑,这些业务逻辑应该在业务层处理,避免对数据库产生逻辑依赖。

● (强制)禁止隐式类型转换。

● (强制)禁止在where条件列上使用函数,会导致索引失效。

● (强制)业务允许的情况下,事务里包含SQL语句越少越好,尽量不超过5个。因 为过长的事务会导致锁数据较久,MySQL内部缓存、连接消耗过多等问题。

● (强制)拒绝大事务。

● (强制)所有的字符存储与表示,均以utf-8或者utf8mb4编码,表和字段需要有 注释,注意字符统计函数的区别。

● (强制)避免使用自然连接(natural join)。

● (推荐)事务里更新语句尽量基于主键或unique key,否则会产生间隙锁,内部 扩大锁定范围,导致系统性能下降,产生死锁。

● (推荐)尽量不使用外键与级联,外键概念可以在应用层解决。

● (推荐)in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素 数量,控制在500个之内。

● (推荐)在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的 分页语句。

● (推荐)减少使用无法利用索引的order by,和业务沟通能不排序就不排序,或 将排序放到程序端去做。

● (推荐)order by、group by、distinct这些SQL尽量利用索引直接检索出排序好 的数据。

● (推荐)包含了order by、group by、distinct这些查询的语句,where条件过滤 出来的结果集请保持在1000行以内,否则SQL会很慢。

● (推荐)能确定返回结果只有一条时,使用 limit 1。在保证数据不会有误的前提 下,能确定结果集数量时,多使用limit,尽快的返回结果。

● (推荐)涉及到复杂SQL时,务必先参考已有索引设计,先explain。先explain的 好处是可以为了利用索引,增加更多查询限制条件。

● (推荐)简单SQL拆分,不以代码处理复杂为由。

● (推荐)使用join时,where条件尽量充分利用同一表上的索引。

● (推荐)考虑使用union all,少使用union,注意考虑去重。union all不去重,而 少了排序操作,速度相对比union要快,如果没有去重的需求,优先使用union all。

● (推荐)order by .. limit。这种查询更多的是通过索引去优化。

● (推荐)不要在SQL中进行复杂的运算或业务逻辑,这些都应该在业务层解决。

● (推荐)建议使用合理的分页方式以提高分页效率,大页情况下不使用跳跃式分 页。

● (推荐)避免频繁对表进行COUNT操作。对大数据量表进行COUNT操作非常耗 时,一般都是秒级响应速度。如果有频繁对表进行COUNT操作的需求,请引入专 门的计数表解决。

● (推荐)delete,update语句改成select再explain。select最多导致数据库慢,写操 作才是锁表的罪魁祸首。

● (推荐)为了减少与数据库交互的次数,可以适度采用批量SQL语句。例如:

INSERT INTO … VALUES (XX),(XX),(XX)....(XX); 这里XX的个数建议100个以内。

● (推荐)TRUNCATE TABLE 比 DELETE速度快,且使用的系统和日志资源少,如 果删除的表上没有TRIGGER,且进行全表删除,建议使用TRUNCATE TABLE。

说明

TRUNCATE TABLE不会把删除的数据写到日志文件中。

● (推荐)尽量不要使用负向查询,避免全表扫描。

● (推荐)避免三个表以上join。需要join的字段,数据类型必须绝对一致;多表关 联查询时,保证被关联的字段需要有索引;在多表join中,尽量选取结果集较小的 表作为驱动表,来join其他表。

● (推荐)任何新的select,update,delete上线,都要先explain,看索引使用情况,

尽量避免extra列出现:Using File Sort,Using Temporary,rows超过1000的要 谨慎上线。每天进行慢日志统计分析,去除慢日志语句。

20.1.4 数据库权限规范

● (强制)所有DDL(例如:建表,更改表结构等)只有通过Review后,由DBA进 行通过DAS,在业务低峰期操作上线。

● (强制)权限要细粒度控制,读写权限分开,运维和开发权限要分开。

● (强制)DDL操作保留操作日志。

相關文件