MySQL 基础篇

三范式

MySQL 军规

MySQL 配置

MySQL 用户管理和权限设置

MySQL 常用函数介绍

MySQL 字段类型介绍

MySQL 多列排序

MySQL 行转列 列转行

MySQL NULL 使用带来的坑

MySQL AND 和 OR 联合使用带来的坑

MySQL 触发器的使用

转载:

《58到家数据库30条军规解读》

《赶集mysql军规》

《58到家MySQL军规升级版》

基础规范

必须使用 InnoDB 存储引擎

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

表字符集默认使用 utf8,必要时候使用 utf8mb4

解读:万国码,无需转码,无乱码风险,节省空间,utf8mb4 是 utf8 的超集,有存储4字节例如表情符号时,使用它。

数据表、数据字段必须加入中文注释

禁止使用存储过程、视图、触发器、Event

解读:高并发大数据的互联网业务,架构设计思路是“解放数据库 CPU,将计算转移到服务层”,并发量大的情况下,这些功能很可能将数据库拖死,业务逻辑放到服务层具备更好的扩展性,能够轻易实现“增机器就加性能”。数据库擅长存储与索引,CPU 计算还是上移吧。

禁止存储大文件或者大照片

解读:为何要让数据库做它不擅长的事情?大文件和照片存储在文件系统,数据库里存 URI 多好。

控制单表数据量,单表记录控制在千万级

平衡范式与冗余,为提高效率可以牺牲范式设计,冗余数据

命名规范

只允许使用内网域名,而不是 ip 连接数据库

线上环境、开发环境、测试环境数据库内网域名遵循命名规范

业务名称:xxx

线上环境:dj.xxx.db

开发环境:dj.xxx.rdb

测试环境:dj.xxx.tdb

从库在名称后加-s标识,备库在名称后加-ss标识

线上从库:dj.xxx-s.db

线上备库:dj.xxx-sss.db

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

表名 t_xxx,非唯一索引名 idx_xxx,唯一索引名 uniq_xxx

表设计规范

单实例表个数必须控制在2000个以内

单表分表个数必须控制在1024个以内

单表列数目必须小于30

表必须有主键,例如自增主键,推荐使用 UNSIGNED 整数为主键

解读:

  • 主键递增,数据行写入可以提高插入性能,可以避免 page 分裂,减少表碎片,提升空间和内存的使用;
  • 主键要选择较短的数据类型,InnoDB 引擎普通索引都会保存主键的值,较短的数据类型可以有效的减少索引的磁盘空间,提高索引的缓存效率;
  • 无主键的表删除,在 row 模式的主从架构,会导致备库夯住;

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

解读:外键会导致表与表之间耦合,update 与 delete 操作都会涉及相关联的表,十分影响 SQL 的性能,甚至会造成死锁。高并发情况下容易造成数据库性能,大数据高并发业务场景数据库使用以性能优先。

建议将大字段,访问频度低的字段拆分到单独的表中存储,分离冷热数据

字段设计规范

必须把字段定义为 NOT NULL 并且提供默认值

解读:

  • nul l的列使索引/索引统计/值比较都更加复杂,对 MySQL 来说更难优化;
  • null 这种类型 MySQL 内部需要进行特殊处理,增加数据库处理记录的复杂性;同等条件下,表中有较多空字段的时候,数据库的处理性能会降低很多;
  • null 值需要更多的存储空,无论是表还是索引中每行中的 null 的列都需要额外的空间来标识;
  • 对 null 的处理时候,只能采用 is null 或 is not null,而不能采用 =、in、<、<>、!=、not in 这些操作符号。如:where name != 'shenjian',如果存在 name 为 null 值的记录,查询结果就不会包含 name 为 null 值的记录;

禁止使用 TEXT、BLOB 类型

解读:会浪费更多的磁盘和内存空间,非必要的大量的大字段查询会淘汰掉热数据,导致内存命中率急剧降低,影响数据库性能。

禁止使用小数存储货币

解读:使用整数吧,小数容易导致钱对不上。

必须使用 varchar(20) 存储手机号

解读:

  • 涉及到区号或者国家代号,可能出现+-();
  • varchar 可以支持模糊查询,例如:like“138%”;

禁止使用 ENUM,可使用 TINYINT 代替

解读:

  • 增加新的 ENUM 值要做 DDL 操作;
  • ENUM 的内部实际存储就是整数;

用好数值类型

解读:

  • tinyint(1Byte):有符号(signed)范围是-128到127,无符号(unsigned)范围是0到255。
  • smallint(2Byte):有符号(signed)范围是-32768到32767,无符号(unsigned)范围是0到65535。
  • mediumint(3Byte):有符号(signed)范围是-8388608到8388607,无符号(unsigned)范围是0到16777215。
  • int(4Byte):有符号(signed)范围是-2147483648到2147483647,无符号(unsigned)范围是0到4294967295
  • bigint(8Byte):有符号(signed)范围是-9223372036854775808到9223372036854775807,无符号(unsigned)范围是0到18446744073709551615

使用 INT UNSIGNED 存储 IPv4,不要用 char(15)

根据业务区分使用 char/varchar

解读:

  • 字段长度固定,或者长度近似的业务场景,适合使用 char,能够减少碎片,查询性能高;
  • 字段长度相差较大,或者更新较少的业务场景,适合使用 varchar,能够减少空间;

根据业务区分使用 datetime/timestamp

解读:前者占用5个字节,后者占用4个字节,存储年使用 YEAR,存储日期使用 DATE,存储时间使用 datetime

索引设计规范

单表索引建议控制在5个以内

解读:

  • 互联网高并发业务,太多索引会影响写性能;
  • 生成执行计划时,如果索引太多,会降低性能,并可能导致 MySQL 选择不到最优索引;
  • 异常复杂的查询需求,可以选择 ES 等更为适合的方式存储;

单索引字段数不允许超过5个

解读:字段超过5个时,实际已经起不到有效过滤数据的作用了。

禁止在更新十分频繁、区分度不高的属性上建立索引

解读:

  • 更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能;
  • 【性别】这种区分度不大的属性,建立索引是没有什么意义的,不能有效过滤数据,性能与全表扫描类似;

建立组合索引,必须把区分度高的字段放在前面

解读:能够更加有效的过滤数据。

非必要不要进行 JOIN 查询,如果要进行 JOIN 查询,被 JOIN 的字段必须类型相同,并建立索引

理解组合索引最左前缀原则,避免重复建设索引,如果建立了(a,b,c),相当于建立了(a), (a,b), (a,b,c)

SQL 使用规范

禁止使用 SELECT *,只获取必要的字段,需要显示说明列属性

解读:

  • 读取不需要的列会增加 CPU、IO、NET 消耗;
  • 不能有效的利用覆盖索引;
  • 使用 SELECT * 容易在增加或者删除字段后出现程序 BUG;

禁止使用 INSERT INTO t_xxx VALUES(xxx),必须显示指定插入的列属性

解读:容易在增加或者删除字段后出现程序BUG。

禁止使用属性隐式转换

解读:SELECT uid FROM t_user WHERE phone=13812345678 会导致全表扫描,而不能命中 phone 索引。

禁止在 WHERE 条件的属性上使用函数或者表达式

解读:SELECT uid FROM t_user WHERE from_unixtime(day)>='2017-02-15' 会导致全表扫描。

正确的写法是:SELECT uid FROM t_user WHERE day>= unix_timestamp('2017-02-15 00:00:00')。

禁止负向查询,以及%开头的模糊查询

解读:

  • 负向查询条件:NOT、!=、<>、!<、!>、NOT IN、NOT LIKE 等,会导致全表扫描;
  • %开头的模糊查询,会导致全表扫描;

禁止大表使用 JOIN 查询,禁止大表使用子查询

解读:会产生临时表,消耗较多内存与 CPU,极大影响数据库性能。

禁止使用 OR 条件,必须改为 IN 查询或者 UNION 查询,IN 的值必须少于50个

解读:旧版本 MySQL 的 OR 查询是不能命中索引的,即使能命中索引,为何要让数据库耗费更多的 CPU 帮助实施查询优化呢。

使用 union all 替代 union,union 有去重开销

limit 高效分页(可选)

解读:limit 越大,效率越低,select id from t limit 10000, 10; 改为 select id from t where id > 10000 limit 10;。

SQL where 条件的顺序不一定需要按照索引的顺序

解读:比如一个联合索引是 name, age,查询的时候 where 条件可以写成 age=10 and name='张三'。

应用程序必须捕获 SQL 异常,并有相应处理

MySQL 军规的更多相关文章

  1. ORM规约变更经典案例---mysql军规

    先介绍一下<MySQL数据库开发的三十六条军规>,这里只介绍核心的,具体内容大家可以自行百度,这是从底层开发人员到管理者必须知道规范.出自58赶集. 写在前面的话: 总是在灾难发生后,才想 ...

  2. mysql 军规 (转载)

    导语 来自一线的实战经验 每一条军规背后都是血淋淋教训 不要华丽,只要实用 若有一条让你受益,慰矣 主要针对数据库开发人员 总是在灾难发生后,才想起容灾的重要性 总是在吃过亏后,才记得曾经有人提醒过 ...

  3. 赶集mysql军规

    总是在灾难发生后,才想起容灾的重要性.总是在吃过亏后,才记得曾经有人提醒过. 一,核心军规 不在数据库做计算,cpu计算务必移至业务层 控制单表数据量,单表记录控制在千万级 控制列数量,字段数控制在2 ...

  4. mysql军规

    总是在灾难发生后,才想起容灾的重要性.总是在吃过亏后,才记得曾经有人提醒过. 一,核心军规 不在数据库做计算,cpu计算务必移至业务层 控制单表数据量,单表记录控制在千万级 控制列数量,字段数控制在2 ...

  5. MySQL军规升级版(转)

    一.基础规范 表存储引擎必须使用InnoDB 表字符集默认使用utf8,必要时候使用utf8mb4 解读:(1)通用,无乱码风险,汉字3字节,英文1字节(2)utf8mb4是utf8的超集,有存储4字 ...

  6. 转载&修改:赶集mysql军规

    个人认为以下军规主要为了适应海量数据场景,对于业务复杂性系统并一定完全按照此军规   一,核心军规 不在数据库做计算,cpu计算务必移至业务层 控制单表数据量,单表记录控制在千万级 控制列数量,字段数 ...

  7. MySQL语句高效写法整理

    优先使用INNER JOIN 多表关联查询,扫描的行尽量少         关联的时候下条件减少扫描的行数 SELECT     ... FROM     ad_ad_summary_for_pos_ ...

  8. MySQL最佳实践

    一.核心军规         - 不在数据库做运算:cpu计算务必移至业务层         - 控制单表数据量:单表记录控制在1000w         - 控制列数量:字段数控制在20以内     ...

  9. MySQL 触发器的使用

    MySQL 基础篇 三范式 MySQL 军规 MySQL 配置 MySQL 用户管理和权限设置 MySQL 常用函数介绍 MySQL 字段类型介绍 MySQL 多列排序 MySQL 行转列 列转行 M ...

随机推荐

  1. T-MAX组--项目冲刺(第一天)

    THE FIRST DAY 项目相关 作业相关 具体描述 所属班级 2019秋福大软件工程实践Z班 作业要求 团队作业第五次-项目冲刺 作业正文 T-MAX组--项目冲刺(第一天) 团队名称 T-MA ...

  2. legend3---16、网站的安全性问题

    legend3---16.网站的安全性问题 一.总结 一句话总结: 通过客户端传递参数的方式也是有些危险,需要注意 单纯的获取数据的方法还好,但是 修改数据库方法一定要同时做前后端验证 1.php的b ...

  3. Hortonworks,快速上手 Hadoop 的套件

    最近我在思考的一件事情:如何帮助团队 SQL 开发快速掌握大数据相关技术呢?面对疯狂暴涨的数据,SQL Server 存储成本越来越高了,日志的增长量也极大超过预期,隔三差五总有空间不足导致的应用异常 ...

  4. 安卓P2P开源项目

    https://github.com/LinYaoTian/P2PChat 一个基于局域网的 Android P2P 聊天系统 https://github.com/ddssingsong/webrt ...

  5. python笔记7 logging模块 hashlib模块 异常处理 datetime模块 shutil模块 xml模块(了解)

    logging模块 日志就是记录一些信息,方便查询或者辅助开发 记录文件,显示屏幕 低配日志, 只能写入文件或者屏幕输出 屏幕输出 import logging logging.debug('调试模式 ...

  6. PHP操作文件常用函数

    [获取文件信息的函数] basename($path[,扩展名]) 返回文件路径中去掉路径后的文件名称."/root/a.txt"输出a.txt;带上.txt输出a. dirnam ...

  7. ISO/IEC 9899:2011 条款5——5.2.4 环境限制

    5.2.4 环境限制 1.翻译与执行环境都约束了语言翻译器和库的实现.下面概述了对一个顺应标准实现的语言相关的环境限制:库相关的限制在条款7中讨论. 5.2.4.1 翻译限制 1.实现应该能够翻译并执 ...

  8. js下利用userData实现客户端保存表单数据

    对于多数网页制作的朋友,实现在客户端保存在网页表单上的信息,比较多的是采用Cookie技术来实现,这些功能例如:下拉列表框选择的选项,文本框输入的数据等. 事实上,我们可以利用微软DHTML默认行为中 ...

  9. python面向对象之花里胡哨大杂烩

    python类的魔法方法之__str__.__repr__.__format__.__module__.__class__.__slots__.__call__.__del__(析构函数) 字符串的内 ...

  10. html转图片网页截屏(二)PhantomJS

    关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS ...