sql datetime 排序_超全的数据库建表/SQL/索引规范,建议贴在工位上!

3d2637bfef7b8d20770ad77487ef888f.png

作者:浮雷来源:juejin.im/post/6871969929365553165

「背景」

因为工作岗位的原因,负责制定了关于后端组数据库的规约规范,作为所有产品线的规范,历经几版的修改,最终形成下边的文本。

规范在整个后端执行也有大半年的时间,对于整个团队在开发阶段就减少不恰当的建表语句、错误SQL、错误的索引有积极的意义,故分享出来给大家参考。

下边分为「建表规约、SQL规约、索引规约」三个部分,每部分的每一条都有「强制、建议」两个级别,大家在参考时,根据自己公司的情况来权衡。

「一、建表规约」

「【强制】(1) 存储引擎必须使用InnoDB」

解读:InnoDB支持事物、行级锁、并发性能更好,CPU及内存缓存页优化使得资源利用率更高。

「【强制】(2)每张表必须设置一个主键ID,且这个主键ID使用自增主键(在满足需要的情况下尽量短),除非在分库分表环境下」

解读:由于InnoDB组织数据的方式决定了需要有一个主键,而且若是这个主键ID是单调递增的可以有效提高插入的性能,避免过多的页分裂、减少表碎片提高空间的使用率。而在分库分表环境下,则需要统一来分配各个表中的主键值,从而避免整个逻辑表中主键重复。

「【强制】(3)必须使用utf8mb4字符集」

解读:在Mysql中的UTF-8并非“真正的UTF-8”,而utf8mb4”才是真正的“UTF-8”。

「【强制】(4) 数据库表、表字段必须加入中文注释」

解读:大家都别懒。

「【强制】(5) 库名、表名、字段名均小写,下划线风格,不超过32个字符,必须见名知意,禁止拼音英文混用」

解读:约定。

「【强制】(6)单表列数目必须小于30,若超过则应该考虑将表拆分」

解读:单表列数太多使得Mysql服务器处理InnoDB返回数据之间的映射成本太高。

「【强制】(7)禁止使用外键,如果有外键完整性约束,需要应用程序控制」

解读:外键会导致表与表之间耦合,UPDATE与DELETE操作都会涉及相关联的表,十分影响SQL的性能,甚至会造成死锁。

「【强制】(8)必须把字段定义为NOT NULL并且提供默认值」

「解读:」

  • NULL的列使索引/索引统计/值比较都更加复杂,对MySQL来说更难优化;

  • NULL这种类型Msql内部需要进行特殊处理,增加数据库处理记录的复杂性;同等条件下,表中有较多空字段的时候,数据库的处理性能会降低很多;

  • NULL值需要更多的存储空,无论是表还是索引中每行中的NULL的列都需要额外的空间来标识。

「【强制】(9)禁用保留字,如DESC、RANGE、MARCH等,请参考Mysql官方保留字」

「【强制】(10)如果存储的字符串长度几乎相等,使用CHAR定长字符串类型。」

解读:能够减少空间碎片,节省存储空间。

「【建议】(11)在一些场景下,考虑使用TIMESTAMP代替DATETIME」

「解读:」

  • 这两种类型的都能表达"yyyy-MM-dd HH:mm:ss"格式的时间,TIMESTAMP只需要占用4个字节的长度,可以存储的范围为(1970-2038)年,在各个时区,所展示的时间是不一样的;

  • 而DATETIME类型占用8个字节,对时区不敏感,可以存储的范围为(1001-9999)年。

「【建议】(12)当心自动生成的Schema,建议所有的Schema手动编写」

解读:对于一些数据库客户端不要太过信任。

「二、SQL规约」

「【建议】 (1) 为了充分利用缓存,不允许使用自定义函数、存储函数、用户变量」

解读:如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、Mysql库中的系统表,其查询结果都不会被缓存。比如函数NOW()或者CURRENT_DATE()会因为不同的查询时间,返回不同的查询结果。

【强制】(2)在查询中指定所需的列,而不是直接使用“ ”返回所有的列

「解读:」

  • 读取不需要的列会增加CPU、IO、NET消耗;

  • 不能有效的利用覆盖索引。

「【强制】(3)不允许使用属性隐式转换」

解读:假设我们在手机号列上添加了索引,然后执行下面的SQL会发生什么?explain SELECT user_name FROM parent WHERE phone=13812345678; 很明显就是索引不生效,会全表扫描。

「【建议】(4)在WHERE条件的属性上使用函数或者表达式」

解读:Mysql无法自动解析这种表达式,无法使用到索引。

「【强制】(5)禁止使用外键与级联,一切外键概念必须在应用层解决」

解读:外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

「【建议】(6)应尽量避免在WHERE子句中使用or作为连接条件」

解读:根据情况可以选择使用UNION ALL来代替OR。

「【强制】(7)不允许使用%开头的模糊查询」

解读:根据索引的最左前缀原理,%开头的模糊查询无法使用索引,可以使用ES来做检索。

「三、索引规约」

「【建议】(1)避免在更新比较频繁、区分度不高的列上单独建立索引」

解读:区分度不高的列单独创建索引的优化效果很小,但是较为频繁的更新则会让索引的维护成本更高。

「【强制】(2) JOIN的表不允许超过五个。需要JOIN的字段,数据类型必须绝对一致; 多表关联查询时,保证被关联的字段需要有索引」

解读:太多表的JOIN会让Mysql的优化器更难权衡出一个“最佳”的执行计划(可能性为表数量的阶乘),同时要注意关联字段的类型、长度、字符编码等等是否一致。

「【强制】(3)在一个联合索引中,若第一列索引区分度等于1,那么则不需要建立联合索引」

解读:索引通过第一列就能够完全定位的数据,所以联合索引的后边部分是不需要的。

「【强制】(4)建立联合索引时,必须将区分度更高的字段放在左边」

解读:区分度更高的列放在左边,能够在一开始就有效的过滤掉无用数据。提高索引的效率,相应我们在Mapper中编写SQL的WHERE条件中有多个条件时,需要先看看当前表是否有现成的联合索引直接使用,注意各个条件的顺序尽量和索引的顺序一致。

「【建议】(5)利用覆盖索引来进行查询操作,避免回表」

解读:覆盖查询即是查询只需要通过索引即可拿到所需DATA,而不再需要再次回表查询,所以效率相对很高。我们在使用EXPLAIN的结果,extra列会出现:"using index"。这里也要强调一下不要使用“SELECT * ”,否则几乎不可能使用到覆盖索引。

「【建议】(6)在较长VARCHAR字段,例如VARCHAR(100)上建立索引时,应指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可」

解读:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,若长度为20的索引,区分度会高达90%以上,则可以考虑创建长度例为20的索引,而非全字段索引。例如可以使用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,则此时可以利用索引排序;

  • 反例:在查询条件中包含了范围查询,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引a_b无法排序。

「【建议】(8)在where中索引的列不能某个表达式的一部分,也不能是函数的参数」

解读:即是某列上已经添加了索引,但是若此列成为表达式的一部分、或者是函数的参数,Mysql无法将此列单独解析出来,索引也不会生效。

「【建议】 (9)我们在where条件中使用范围查询时,索引最多用于一个范围条件,超过一个则后边的不走索引」

解读:Mysql能够使用多个范围条件里边的最左边的第一个范围查询,但是后边的范围查询则无法使用。

「【建议】 (10)在多个表进行外连接时,表之间的关联字段类型必须完全一致」

解读:当两个表进行Join时,字段类型若没有完全一致,则加索引也不会生效,这里的完全一致包括但不限于字段类型、字段长度、字符集、collection等等。

「参考资料」

  • 《High.Performance.MySQL.3rd.Edition》

  • 《阿里巴巴java开发手册》

e3a70efc86f62580c37e086736363813.png

-END-

ec8417e5414b2fd34c05d25bcec1c413.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有了它,从此成为自带BGM的主角~

有了它 自带BGM不是事儿 这还是一篇卖货的文章 welcome 炎热的夏天,一场雷阵雨也浇灭不了的躁动,何不来点音乐啤酒,点燃内心的蠢蠢欲动, 放肆的音乐节奏,张扬的夏日心情。 然而单独用手机音乐播放器听,单薄…

oracle导入视图报错,exp/imp 报错处理(EXP-00003 / IMP-00019 / IMP-00058)

MOS 文章参考OERR: EXP 3 "no storage definition found for segment(%lu, %lu)" (文档 ID 21599.1)EXP-00003 When Exporting From 9.2.0.5.0 Or Any Higher Release With A Pre-9.2.0.5.0 Export Client (文档 ID 274076.1)一、EXP 导出报错(数据库版本 11.2.0.4.0…

重磅大礼!100本《机器学习》by周志华,免费送!

我 相 信 这 么 优秀 的 你 已 经 置 顶 了 我 亲爱的小伙伴们~ 我可想死你们啦! 福利小编再次上线 继续给大家送温暖~ 100本! 《机器学习》 by 周志华 内容简介 机器学习是计算机科学与人工智能的重要分支领域. 本书作为该领域的入门教材&a…

动态箭头gif图标_别以为只有专业人士才能做出酷炫的#动态跑分图#

如果经常关注数据可视化的话,你可能会发现一种流行的动态图表形式——动态跑分图(bar chart race)。这种动态图表的精髓是,通过数据范围的变化(通常是以日期为主),以条形图展现各数据序列间的关…

什么是云原生?

> 一千个读者眼里有一千个哈姆雷特,本号近半年零零散散写了一些云原生、Devops的文章, 最近系统阅读微软Docs, 今天开始结合自己的实践专题意译[云原生]。近几年,云原生成为了软件行业的驱动力。这是一种构建大型复杂系统的新…

宇宙十大不为人知的事情

仰望星空,才知人类如何渺小可怜,还需要继续思考很多年才知道,科学的尽头是神学。宇宙有你想象的到的所有东西,还有你想象不道的更多东西,就比如以下的宇宙十大真相。 一、宇宙空洞 除了黑洞,宇宙中另一种结…

idea shell 中的函数 跳转_SpringBoot项目打包+shell脚本部署实践,太有用了

本篇和大家分享的是springboot打包并结合shell脚本命令部署,重点在分享一个shell程序启动工具,希望能便利工作;profiles指定不同环境的配置maven-assembly-plugin打发布压缩包分享shenniu_publish.sh程序启动工具linux上使用shenniu_publish.…

阅读源码的真正价值

大家好,我是Z哥。最近有位小伙伴求职遇到一些挫折,来找到我聊,其中有问到一个涉及到「阅读源码的必要性」的问题:“有很多场面试,面试官都有问到某个框架的某个功能是怎么实现的,难道真的要去看源码吗&…

vst3插件_Steinberg发布新的VST 3.7 SDK,音乐软件开发者速来围观

Steinberg日前宣布最新的VST SDK(软件开发工具包)即将面市。最新的VST 3.7引入了多项SDK接口增强功能,使VST3宿主和插件之间的集成达到了新的水平,还包括新的VST3项目生成器、改进的文档以及对MIDI 2.0的支持,还可以开…

GitHub 2017 年度报告,最受欢迎的编程语言是?

GitHub 每年都会在年度盛会中推出数据报告,其中列出了一些年度的数据,包括其网站中最受欢迎的编程语言、开源项目等。今年的数据更是让人眼前一亮,Python 这匹编程语言中的黑马,势不可挡! 编程语言之间的战争就是一场持…

python except用法和作用_121个问题答对80%那么恭喜你,Python的高薪工作迟早有你一份...

1. Python和Java、PHP、C、C#、C等其他语言的对比?2. 简述解释型和编译型编程语言?3. 代码中要修改不可变数据会出现什么问题? 抛出什么异4. print 调用 Python 中底层的什么方法?5. 简述你对 input()函数的理解?6. Python解释器种类以及特点&#xf…

GraphQL:来来来,Union

Union就是把不相干的一些数据实体,合并起来,一起供外部查询。不用像webapi,完成查询不同的数据,需要多次请求。一次请求,获取多样数据,减少请求次数,这也是GraphQL的优势之一。怎么弄&#xff0…

每个程序员都应该知道的基础数论

这篇文章讨论了数论中每个程序员都应该知道的几个重要概念。本文的内容既不是对数论的入门介绍,也不是针对数论中任何特定算法的讨论,而只是想要做为数论的一篇参考。如果读者想要获取关于数论的更多细节,文中也提供了一些外部的参考文献&…

powerbi视觉对象_玩转Power BI的图片可视化

​制作可视化报告时,为了展示效果,有时候需要用图片来展示,在 Power BI 中,关于图片的自定义视觉对象主要有下面三个,利用他们可以很轻松的进行图片可视化。下面来看看这些视觉对象的效果。样本数据如下:为…

东南大学计算机网络_东南大学,2020年东南大学高考录取分数线分析

各位读者大家好,今天给大家介绍的是南京重点大学—东南大学。小编一直从事高等教育领域的写作,感兴趣的读者可以关注一下小编~1.学校基础东南大学,简称“东大”,是中华人民共和国教育部直属、中央直管副部级建制的全国重点大学&am…

Goodbye 2020,Welcome 2021 | 沉淀 2021

引言2021年,已开启二月的篇章,农历新年也张灯结彩而来,只不过要留守过年。在这辞旧迎新之际,踏入而立之年之时,正是算账的好时候,数一数今年的成长,讲一讲来年的期望,最重要的还是要…

程序员必须知道的十大基础实用算法及其讲解

本文盘点程序员必须知道的十大基础实用算法及其讲解。 算法一:快速排序算法 快速排序是由东尼霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(nlogn) 次比较。在最坏状况下则需要Ο(n2) 次比较,但这种状况并不常见。事实上&#…

sql 日期和当前日期时间差_详解PostgreSQL 如何获取当前日期时间

概述开发数据库应用或者调试代码时,经常需要获取系统的当前日期和时间,今天主要看一下 PostgreSQL 中提供的相关函数。一、当前日期CURRENT_DATECURRENT_DATE 函数用于获取数据库服务器的当前日期:postgres# SELECT CURRENT_DATE;调用该函数时…

我们只知大势将至,却不知未来已来

❈ 凯文•凯利 《必然》: 未来的一切事物的生命都将是无穷尽的升级,而且迭代的速度不断的在加速。包括看得见的事物,也包括看不见的审美观和价值观。无论你使用一项工具的时间有多长,不断的升级都会把你变成一个菜鸟,从…

c#爬虫-1688官网自动登录

背景在1688官网里面有很多信息是需要登录才能看得到的,比如商家的联系电话等等。那么我们在抓取它的网页的时候,肯定是需要维持登录状态才能得到对应的内容。这里面就会涉及到自动登录的问题。登录地址https://login.1688.com/member/signin.htm自动登录…