0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MySQL规范

数据分析与开发 来源:数据分析与开发 作者:数据分析与开发 2020-11-19 15:39 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

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

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

建表规约

【强制】:①存储引擎必须使用 InnoDB

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

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

解读:由于 InnoDB 组织数据的方式决定了需要有一个主键,而且若是这个主键 ID 是单调递增的可以有效提高插入的性能,避免过多的页分裂、减少表碎片提高空间的使用率。

而在分库分表环境下,则需要统一来分配各个表中的主键值,从而避免整个逻辑表中主键重复。

【强制】:③必须使用 utf8mb4 字符集

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

【强制】:④数据库表、表字段必须加入中文注释

解读:大家都别懒。

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

解读:约定。

【强制】:⑥单表列数目必须小于 30,若超过则应该考虑将表拆分

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

【强制】:⑦禁止使用外键,如果有外键完整性约束,需要应用程序控制

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

【强制】:⑧必须把字段定义为 NOT NULL 并且提供默认值

解读:

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

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

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

【强制】:⑨禁用保留字,如 DESC、RANGE、MARCH 等

解读:请参考 MySQL 官方保留字。

【强制】:⑩如果存储的字符串长度几乎相等,使用 CHAR 定长字符串类型

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

【建议】:⑪在一些场景下,考虑使用 TIMESTAMP 代替 DATETIME

解读:

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

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

【建议】:⑫当心自动生成的 Schema,建议所有的 Schema 手动编写

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

SQL 规约

【建议】:①为了充分利用缓存,不允许使用自定义函数、存储函数、用户变量

解读:如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、MySQL 库中的系统表,其查询结果都不会被缓存。

比如函数 NOW() 或者 CURRENT_DATE() 会因为不同的查询时间,返回不同的查询结果。

【强制】:②在查询中指定所需的列,而不是直接使用“ *”返回所有的列 解读:

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

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

【强制】:③不允许使用属性隐式转换

解读:假设我们在手机号列上添加了索引,然后执行下面的 SQL 会发生什么?

explain SELECT user_name FROM parent WHERE phone=13812345678;很明显就是索引不生效,会全表扫描。

【建议】:④在 WHERE 条件的属性上使用函数或者表达式

解读:MySQL 无法自动解析这种表达式,无法使用到索引。 【强制】:⑤禁止使用外键与级联,一切外键概念必须在应用层解决

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

【建议】:⑥应尽量避免在 WHERE 子句中使用 or 作为连接条件

解读:根据情况可以选择使用 UNION ALL 来代替 OR。 【强制】:⑦不允许使用 % 开头的模糊查询

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

索引规约

【建议】:①避免在更新比较频繁、区分度不高的列上单独建立索引

解读:区分度不高的列单独创建索引的优化效果很小,但是较为频繁的更新则会让索引的维护成本更高。 【强制】:②JOIN 的表不允许超过五个。需要 JOIN 的字段,数据类型必须绝对一致; 多表关联查询时,保证被关联的字段需要有索引

解读:太多表的 JOIN 会让 MySQL 的优化器更难权衡出一个“最佳”的执行计划(可能性为表数量的阶乘),同时要注意关联字段的类型、长度、字符编码等等是否一致。 【强制】:③在一个联合索引中,若第一列索引区分度等于 1,那么则不需要建立联合索引

解读:索引通过第一列就能够完全定位的数据,所以联合索引的后边部分是不需要的。 【强制】:④建立联合索引时,必须将区分度更高的字段放在左边

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

解读:覆盖查询即是查询只需要通过索引即可拿到所需 DATA,而不再需要再次回表查询,所以效率相对很高。

我们在使用 EXPLAIN 的结果,extra 列会出现:"using index"。这里也要强调一下不要使用“SELECT * ”,否则几乎不可能使用到覆盖索引。

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

解读:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,若长度为 20 的索引,区分度会高达 90% 以上,则可以考虑创建长度例为 20 的索引,而非全字段索引。

例如可以使用 SELECT COUNT(DISTINCT LEFT(lesson_code, 20))/COUNT(*) FROM lesson;来确定 lesson_code 字段字符长度为 20 时文本区分度。

【建议】:⑦如果有 ORDER BY 的场景,请注意利用索引的有序性

ORDER BY 最后的字段是联合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。

解读:

假设有查询条件为 WHERE a=? and b=? ORDER BY c;存在索引:a_b_c,则此时可以利用索引排序。

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

【建议】:⑧在 Where 中索引的列不能某个表达式的一部分,也不能是函数的参数

解读:即是某列上已经添加了索引,但是若此列成为表达式的一部分、或者是函数的参数,MySQL 无法将此列单独解析出来,索引也不会生效。 【建议】:⑨我们在 Where 条件中使用范围查询时,索引最多用于一个范围条件,超过一个则后边的不走索引

解读:MySQL 能够使用多个范围条件里边的最左边的第一个范围查询,但是后边的范围查询则无法使用。 【建议】:⑩在多个表进行外连接时,表之间的关联字段类型必须完全一致

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

参考资料:

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

《阿里巴巴java开发手册》

责任编辑:xj

原文标题:CTO 要我把这份 MySQL 规范贴在工位上!

文章出处:【微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据库
    +关注

    关注

    7

    文章

    3993

    浏览量

    67719
  • MySQL
    +关注

    关注

    1

    文章

    897

    浏览量

    29216

原文标题:CTO 要我把这份 MySQL 规范贴在工位上!

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    工业数据中台支持接入MySQL数据库吗

    工业数据中台完全支持接入MySQL数据库 ,且通过数据同步、集成与治理等技术手段,能够充分发挥MySQL在数据存储与事务处理方面的优势,同时弥补其在数据分析与共享能力上的不足,具体分析如下: 技术
    的头像 发表于 12-04 11:23 167次阅读
    工业数据中台支持接入<b class='flag-5'>MySQL</b>数据库吗

    CentOS 7下MySQL 8双主热备高可用架构全解

    Centos7部署MySQL8+keepalived双主热备(含Keepalived配置与GTID同步优化方案) 架构拓扑原理 GTID同步 VIP 192.168.1.100 MySQL主节点1
    的头像 发表于 08-12 17:08 596次阅读

    MySQL 8.0性能优化实战指南

    作为一名运维工程师,MySQL数据库优化是我们日常工作中最具挑战性的任务之一。MySQL 8.0作为当前主流版本,在性能、安全性和功能上都有了显著提升,但如何充分发挥其潜力,仍需要我们掌握正确的优化策略。
    的头像 发表于 07-24 11:48 534次阅读

    MySQL数据备份与恢复策略

    数据是企业的核心资产,MySQL作为主流的关系型数据库管理系统,其数据的安全性和可靠性至关重要。本文将深入探讨MySQL的数据备份策略、常用备份工具以及数据恢复的最佳实践,帮助运维工程师构建完善的数据保护体系。
    的头像 发表于 07-14 11:11 462次阅读

    企业级MySQL数据库管理指南

    在当今数字化时代,MySQL作为全球最受欢迎的开源关系型数据库,承载着企业核心业务数据的存储与处理。作为数据库管理员(DBA),掌握MySQL的企业级部署、优化、维护技能至关重要。本文将从实战角度出发,系统阐述MySQL在企业环
    的头像 发表于 07-09 09:50 504次阅读

    MySQL数据库是什么

    MySQL数据库是一种 开源的关系型数据库管理系统(RDBMS) ,由瑞典MySQL AB公司开发,后被Oracle公司收购。它通过结构化查询语言(SQL)进行数据存储、管理和操作,广泛应用于Web
    的头像 发表于 05-23 09:18 912次阅读

    除了增删改查你对MySQL还了解多少

    我们都知道MySQL服务器的默认端口为3306,之后就在这个端口号上等待客户端进程进行连接(MySQL服务器会默认监听3306端口)。
    的头像 发表于 04-14 17:20 513次阅读

    从Delphi、C++ Builder和Lazarus连接到MySQL数据库

      从 Delphi、C++ Builder 和 Lazarus 连接到 MySQL 数据库 MySQL 数据访问组件(MyDAC)是一个组件库,提供从 Delphi 和 C++ Builder
    的头像 发表于 01-20 13:47 1314次阅读
    从Delphi、C++ Builder和Lazarus连接到<b class='flag-5'>MySQL</b>数据库

    使用插件将Excel连接到MySQL/MariaDB

    使用插件将 Excel 连接到 MySQL/MariaDB 适用于 MySQL 的 Devart Excel 插件允许您将 Microsoft Excel 连接到 MySQL 或 MariaDB
    的头像 发表于 01-20 12:38 1129次阅读
    使用插件将Excel连接到<b class='flag-5'>MySQL</b>/MariaDB

    适用于MySQL和MariaDB的Python连接器:可靠的MySQL数据连接器和数据库

    适用于 MySQL 和 MariaDB 的 Python 连接器 Python Connector for MySQL 是一种可靠的连接解决方案,用于从 Python 应用程序访问 MySQL
    的头像 发表于 01-17 12:18 843次阅读
    适用于<b class='flag-5'>MySQL</b>和MariaDB的Python连接器:可靠的<b class='flag-5'>MySQL</b>数据连接器和数据库

    适用于MySQL和MariaDB的.NET连接器

    支持 ORM 的适用于 MySQL 和 MariaDB 的 .NET 连接器 dotConnect for MySQL 是一种高性能 ADO.NET 数据提供程序,可在开发 MySQL 的应用程序
    的头像 发表于 01-16 14:17 791次阅读
    适用于<b class='flag-5'>MySQL</b>和MariaDB的.NET连接器

    MySQL数据库的安装

    MySQL数据库的安装 【一】各种数据库的端口 MySQL :3306 Redis :6379 MongoDB :27017 Django :8000 flask :5000 【二】MySQL 介绍
    的头像 发表于 01-14 11:25 857次阅读
    <b class='flag-5'>MySQL</b>数据库的安装

    windows服务器备份mysql脚本

    osimport reimport datetimeimport subprocess## 需要备份数据库的登录信息mysql_host = { 'test': '10.10.3.207'}db_user
    的头像 发表于 01-02 09:14 667次阅读

    云服务器 Flexus X 实例 MySQL 应用加速测试

    文章目录 目录 文章目录   购买配置   基本配置参考如下:   连接服务器   查询MySQL状态   启动MySQL   添加配置   添加密码并修改权限   性能测试   C#插入数据测试
    的头像 发表于 12-24 12:19 795次阅读
    云服务器 Flexus X 实例 <b class='flag-5'>MySQL</b> 应用加速测试

    数据库数据恢复—Mysql数据库表记录丢失的数据恢复流程

    Mysql数据库故障: Mysql数据库表记录丢失。 Mysql数据库故障表现: 1、Mysql数据库表中无任何数据或只有部分数据。 2、客户端无法查询到完整的信息。
    的头像 发表于 12-16 11:05 996次阅读
    数据库数据恢复—<b class='flag-5'>Mysql</b>数据库表记录丢失的数据恢复流程