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,一经查实,立即删除!

相关文章

大一的时候我上铺一哥们天天说梦话,一夜,他羞涩的说:“我怀孕了。”我们全体晕倒。...

大一的时候我上铺一哥们天天说梦话,一夜,他羞涩的说:“我怀孕了。”我们全体晕倒。转载于:https://blog.51cto.com/275007/115108

Oracle选择填空题中英文,oracle中英文分开排序

中英文分开排序http://hi.baidu.com/flowerhacker/blog/item/dfb0961e383662154034174f.html我同事问了个问题:是将中文和英文分开排序。是先排中文,再排英文的,都按照拼音abc那样排的;字段都是英文打头算作英文,中文打…

有了它,从此成为自带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…

python加油视频教程_TensorFlow 视频教程

###欢迎加入,TensorFlow机器学习社区 232113779TensorFlow / Deep Learning Tutorial in Chinese 中文教程Open Source Technology means to be shared across the world.While TensorFlow is a piece of super advanced technology, there are mostly English supp…

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

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

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

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

揭秘python的5种最佳调试方法_揭秘 IPython 的 5 种最佳调试方法-阿里云开发者社区...

云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策!一个好的集成开发环境(IDE)附带的调试器是开发人员能够拥有的最强大的工具之一&am…

什么是云原生?

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

VForum 2008系列之六:分论坛视频-虚拟世界中的应用

VMware vForum 2008中国虚拟化用户大会与2008年11月4日在北京的国际饭店举行。这是第五论坛的主题介绍:虚拟世界的应用,由VMware资深渠道工程师郭岚演讲。随后是合作伙伴关于该主题的介绍。

linux服务器查配置信息失败,查看Linux服务器的配置信息

一、目标查看服务器的相关配置,例如服务器的品牌,CPU,内存,磁盘等等信息二、环境1.浪潮物理机2.系统centos三、相关查询1. 查看操作系统的版本命令:cat /etc/redhat-releaseCentOS Linux release 7.3.1611 (Core)2.查看系统内核命…

宇宙十大不为人知的事情

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

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

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

阅读源码的真正价值

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

c#中BackGroundWorker控件

一、BackGroundWorker工作步骤 1.向窗体中拖入一个BackGroundWorker控件。 2.在某个方法或者事件中,调用BackGroundWorker的RunWorkerAsync()方法。 3.该方法为异步操作,将自动引发BackGroundWorker的DoWork事件。 4.调用ReportProgress方法将引发Progre…

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

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

linux脚本启三个tomcat,linux 重写Tomcat启停脚本

#!/bin/bash## description: Tomcat start/stop/status script#Location of JAVA_HOMEexport JAVA_HOME/opt/extp/tpc/jdk1.7 # 根据情况更改自己的jdk地址#Add Java binary files to PATHexport PATH$JAVA_HOME/bin:$PATH#CATALINA_HOME is the location of the configuration…

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…

相对论基础的谬误

《广义时空论•像说》附录之五      相对论是相对正确的,因为这个世界能最快描绘一个物体表征的手段是光,即光是标尺。  当物体速度小于光速时,通过对物体发出来的光的探测,可以得出物体的速度表征,及物体的一…