Java后端
,选择 设为星标
优质文章,及时送达
https://juejin.im/post/6871969929365553165
背景
因为工作岗位的原因,负责制定了关于后端组数据库的规约规范,作为所有产品线的规范,历经几版的修改,最终形成下边的文本,规范在整个后端执行也有大半年的时间,对于整个团队在开发阶段就减少不恰当的建表语句、错误SQL、错误的索引有积极的意义,故分享出来给大家参考。
【强制】(1) 存储引擎必须使用InnoDB
InnoDB
支持事物、行级锁、并发性能更好,
CPU
及内存缓存页优化使得资源利用率更高。
【强制】(2)每张表必须设置一个主键ID
,且这个主键ID
使用自增主键(在满足需要的情况下尽量短),除非在分库分表环境下。
InnoDB
组织数据的方式决定了需要有一个主键,而且若是这个主键ID是单调递增的可以有效提高插入的性能,避免过多的页分裂、减少表碎片提高空间的使用率。而在分库分表环境下,则需要统一来分配各个表中的主键值,从而避免整个逻辑表中主键重复。
【强制】(3)必须使用utf8mb4字符集
utf8mb4”
才是真正的
“UTF-8”
。
【强制】(4) 数据库表、表字段必须加入中文注释
【强制】(5) 库名、表名、字段名均小写,下划线风格,不超过32个字符,必须见名知意,禁止拼音英文混用。
【强制】(6)单表列数目必须小于30,若超过则应该考虑将表拆分
【强制】(7)禁止使用外键,如果有外键完整性约束,需要应用程序控制
UPDATE
与
DELETE
操作都会涉及相关联的表,十分影响SQL的性能,甚至会造成死锁。
【强制】(8)必须把字段定义为NOT NULL
并且提供默认值
【强制】(9)禁用保留字,如DESC、RANGE、MARCH
等,请参考Mysql
官方保留字。
【强制】(10)如果存储的字符串长度几乎相等,使用CHAR定长字符串类型。
【建议】(11)在一些场景下,考虑使用TIMESTAMP代替DATETIME。
"yyyy-MM-dd HH:mm:ss"
格式的时间,TIMESTAMP只需要占用4个字节的长度,可以存储的范围为
(1970-2038)
年,在各个时区,所展示的时间是不一样的;b、而
DATETIME
类型占用8个字节,对时区不敏感,可以存储的范围为
(1001-9999)
年。
* 【建议】(12)当心自动生成的Schema
,建议所有的Schema
手动编写。
二、SQL规约
【建议】 (1) 为了充分利用缓存,不允许使用自定义函数、存储函数、用户变量。
NOW()
或者
CURRENT_DATE()
会因为不同的查询时间,返回不同的查询结果。
【强制】(2)在查询中指定所需的列,而不是直接使用“ *”返回所有的列
CPU、IO、NET
消耗 b)不能有效的利用覆盖索引
【强制】(3)不允许使用属性隐式转换
SQL
会发生什么?
explain SELECT user_name FROM parent WHERE phone=13812345678;
很明显就是索引不生效,会全表扫描。
【建议】(4)在WHERE条件的属性上使用函数或者表达式
【强制】(5)禁止使用外键与级联,一切外键概念必须在应用层解决。
【建议】(6)应尽量避免在WHERE子句中使用or作为连接条件
UNION ALL
来代替
OR
【强制】(7)不允许使用%开头的模糊查询
【建议】(1)避免在更新比较频繁、区分度不高的列上单独建立索引
【强制】(2) JOIN的表不允许超过五个。需要JOIN的字段,数据类型必须绝对一致; 多表关联查询时,保证被关联的字段需要有索引。
JOIN
会让Mysql的优化器更难权衡出一个“最佳”的执行计划(可能性为表数量的阶乘),同时要注意关联字段的类型、长度、字符编码等等是否一致。
【强制】(3)在一个联合索引中,若第一列索引区分度等于1,那么则不需要建立联合索引。
【强制】(4)建立联合索引时,必须将区分度更高的字段放在左边
Mapper
中编写
SQL
的
WHERE
条件中有多个条件时,需要先看看当前表是否有现成的联合索引直接使用,注意各个条件的顺序尽量和索引的顺序一致。
【建议】(5)利用覆盖索引来进行查询操作,避免回表
EXPLAIN
的结果,extra列会出现:
"using index"
。这里也要强调一下不要使用
“SELECT * ”
,否则几乎不可能使用到覆盖索引。
【建议】(6)在较长VARCHAR字段,例如VARCHAR(100)上建立索引时,应指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。
SELECT COUNT(DISTINCT LEFT(lesson_code, 20)) / COUNT(*) FROM lesson;
来确定
lesson_code
字段字符长度为20时文本区分度。
【建议】(7)如果有ORDER BY的场景,请注意利用索引的有序性。ORDER BY最后的字段是联合索引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询性能。
WHERE a=? and b=? ORDER BY c;
存在索引:
a_b_c
,则此时可以利用索引排序。2、反例:在查询条件中包含了范围查询,那么索引有序性无法利用,如:
WHERE a>10 ORDER BY b;
索引
a_b
无法排序。
【建议】(8)在where
中索引的列不能某个表达式的一部分,也不能是函数的参数。
【建议】 (9)我们在where
条件中使用范围查询时,索引最多用于一个范围条件,超过一个则后边的不走索引。
【建议】 (10)在多个表进行外连接时,表之间的关联字段类型必须完全一致
-
《High.Performance.MySQL.3rd.Edition》
-
《阿里巴巴java开发手册》
最近整理一份面试资料《Java技术栈学习手册》,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等。 获取方式:点“ 在看,关注公众号 Java后端 并回复 777 领取,更多内容陆续奉上。 推 荐 阅 读 1. 看看人家接口写得,那叫一个优雅! 2. 推荐一款 Java 对象映射神器 3. 5W 字详解分库分表之 Sharding-JDBC 中间件 4. TCP/IP 基础知识总结 5. 面试:如何决定使用 HashMap 还是 TreeMap?
喜欢文章,点个 在看
本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
相关文章
暂无评论...