在互联网公司中,MySQL是使用最多的数据库,那么在并发量大、数据量大的互联网业务中,如果高效的使用MySQL才能保证服务的稳定呢?根据本人多年运维管理经验的总结,梳理了一些核心的开发规范,希望能给大家带来一些帮助。
 
一、基础规范
  • 数据库字符集默认使用utf8mb4,兼容utf8,并支持存储emoji表情等四字节内容
  • 禁止在线上生产环境做数据库压力测试
  • 禁止从测试、开发环境、本机直连线上生产数据库
  • 禁止在数据库中存储明文密码
  • 禁止在数据库中存储图片、文件等大数据
  • 禁止将业务日志实时保存到数据库,建议保存到日志文件,对于统计后的结果再存放到mysql中
  • 禁止线上核心业务使用mysql存储过程、视图、触发器、Event、InnoDB外键约束等,这些容易将业务逻辑和db耦合在一起,而且在MySQL的这些特性中存在严重BUG
  • 业务部门的推广活动,请提前通知dba进行服务和访问评估。
 
二、库表设计
  • 库名、表名、字段名必须使小写字母,并采用下划线分割;对相关功能的表应当使用相同前缀,如job_xxx,前缀通常为库名或依赖主实体对象:数据库名称约定:db_xxx
  • 数据库表默认存储引擎为InnoDB,所有环境禁止使用MyISAM、Memory等其他存储引擎
  • 所有的表及字段都必须有备注,详细说明表及字段的含义
  • 涉及货币金额或其他精度敏感的数据必须使用定点数DECIMAL替代FLOAT和DOUBLE
  • 库名、表名、字段名禁止使用MySQL保留字,如date、like、desc、return等
  • 控制表字段数,单表不超过50个纯INT/20个VARCHAR(10)字段等同存储体积的字段数,上限控制在20~50
  • 字段长度只分配真正需要的空间
问题:使用VARCHAR(5) 和VARCHAR(200) 存储’hello’的磁盘空间开销是一样的,使用更短的列有什么优势吗?
更大的定义列会消耗更多的内存,因为MySQL通常会分配固定大小的内存块来保存内部值,尤其是使用内存临时表进行排序或操作时会特别糟糕
 
三、索引设计
基本规则:索引不是越多越好,能不添加的索引尽量不要添加,过多的索引会严重降低数据插入和更新的效率,并带来更多的读写冲突和死锁!
  • 索引名称必须使用小写,普通索引按照“idx_字段名_字段名[_字段名]”进行命名,唯一索引按照“uniq_字段名_字段名[_字段名]”进行命名”
  • 表必须有主键,推荐使用独立于业务的AUTO_INCREMENT列或全局ID生成器做主键,禁止使用多字段做联合主键
  • 不使用UUID/MD5/HASH等函数生成的无规则值做主键,效率极差
  • 索引数量控制
  • 单张表中索引数量不超过5个
  • 单个索引中的字段数不超过5个
  • 对字符串使用前缀索引,前缀索引长度不超过10个字符
  • 索引字段的顺序需要考虑每个字段去重之后的数量,区分度最大的【个数最多的】放在前面。
  • 合理创建联合索引(避免冗余),符合最左前缀原则:(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c)
  • 可能需要添加索引的字段:
  • ORDER BY,GROUP BY,DISTINCT的字段需要添加在索引的后面
  • UPDATE、DELETE语句需要根据WHERE条件添加索引
  • 对于JOIN操作,需要在JOIN字段上建立索引
  • 线上慎用FORCE INDEX,使用前需要和DBA沟通,并得到DBA的测试允许
  • 线上OLTP系统中禁止使用外键,高并发时极易引起死锁等问题
  • 索引使用禁忌
  • 不使用%前导的查询,如like “%ab”
  • 不使用负向查询,如not in/not like/<>
  • 不在低区分度的列上建立索引,例如“性别”
  • 不在索引列进行数学运算和函数运算
示例:假设在表tab中id建立了索引
  • Select col_A,col_B from tab where id + 1 > 10001 不会使用索引
  • Select col_A,col_B from tab where id > 10001 – 1 会使用索引
 
四、SQL优化
  • 线上尽量少使用大SQL,可能一条大SQL就把整个数据库堵死,将复杂SQL拆分为多条简单SQL,化繁为简
  • 一条SQL只能在一个CPU上运算,如果SQL比较复杂执行效率会非常低【8.0之后开始支持单SQL多CPU核执行,但是效果有限】
  • 简单SQL缓存命中率更高
  • 减少锁表时间
  • 充分利用多核CPU,提高并发效率
  • 减少MySQL端的数学运算和逻辑判断,避免SQL语句出现md5()、order by rand()等
  • 尽量少用SELECT * ,只取需要的数据列, 避免无谓的IO、CPU和网络开销
  • WHERE条件中,同一字段改写OR为IN(),IN包含的值不应过多,默认不超过200个,IN里禁止使用子查询
  • 过滤表记录合并且不去重的情况,改写UNION为UNION ALL
  • 减少使用拼接SQL,使用预编译语句,降低SQL注入概率
  • WHERE条件中的非等值条件(IN、BETWEEN、<、<=、>、>=)会导致使用不了联合索引的后续字段,注意避免
  • WHERE条件比较,字段类型和传入值必须保证类型一致,避免隐式转换
示例:
字段: code varchar(50) NOT NULL COMENT ‘编码’ #code上建立了索引
SELECT id,name,addr from tab_name where code=10001; 不会使用索引
SELECT id,name,addr from tab_name where code='10001'; 会使用索引
  • Limit分页优化
  • 传统分页:
Select * from table limit 10000,10;
LIMIT原理:
Limit 10000,10 偏移量越大则越慢
  • 推荐分页:
  • 分页方式一:
Select * from table WHERE id>=23423 limit 11; #10+1 (每页10条)
Select * from table WHERE id>=23434 limit 11;
  • 分页方式二:
Select * from table WHERE id >= ( select id from table limit 10000,1 ) limit 10;
  • 分页方式三:
Select * from table INNER JOIN (SELECT id from table limit 10000,10) USING(id)
  • 分页方式四:
  • 程序取ID: Select id from table limit 10000,10;
  • Select * from table WHERE ID in(123,456…);
最后说明:
上述规范是多年MySQL数据库使用的经验总结,希望能给大家带来一些启发和帮助!
如果你还想看更多优质原创文章,欢迎关注我的公众号「数据库架构师」,提升数据库技能。
 

一文总结高并发大数据量下MySQL开发规范【军规】的更多相关文章

  1. 【Itext】解决Itext5大并发大数据量下输出PDF发生内存溢出outofmemery异常

    尼玛,这个问题干扰了我两个星期!! 关键字 itext5 outofmemery 内存溢出 大数据 高并发 多线程 pdf 导出 报表 itext 并发 在读<<iText in Acti ...

  2. 大数据量下MySQL插入方法的性能比较

    不管是日常业务数据处理中,还是数据库的导入导出,都可能遇到需要处理大量数据的插入.插入的方式和数据库引擎都会对插入速度造成影响,这篇文章旨在从理论和实践上对各种方法进行分析和比较,方便以后应用中插入方 ...

  3. php和node高并发 大数据量怎么处理

    有的时候可能因为疏忽忘记注册Service直接就使用了,使用那个Service时会报异常.这种情况项目都是可以编译通过的,是一个不太容易发现的BUG,如果那个Service在测试时没有覆盖到这个BUG ...

  4. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  5. 大数据量时Mysql的优化

    (转自网络) 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求.这个时候NoSQL的出现暂时 ...

  6. mysql大数据量下的分页

    mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 测试实验 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from p ...

  7. 大数据量下的SQL Server数据库自身优化

    原文: http://www.d1net.com/bigdata/news/284983.html 1.1:增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情 ...

  8. 大数据量下,分页的解决办法,bubuko.com分享,快乐人生

    大数据量,比如10万以上的数据,数据库在5G以上,单表5G以上等.大数据分页时需要考虑的问题更多. 比如信息表,单表数据100W以上. 分页如果在1秒以上,在页面上的体验将是很糟糕的. 优化思路: 1 ...

  9. mysql百万级别重排主键id(网上的删除重建id在大数据量下会出错)

    网上教程: 先删除旧的主键 再新建主键 :数据量少时没问题,不会出现主键自增空缺间隔的情况(如:1,2,3,5):但是大数据量时会出现如上所述问题(可能是内部mysql多进程或多线程同时操作引起问题) ...

随机推荐

  1. Java已知图片路径下载图片到本地

    public static void main(String[] args) { FileOutputStream fos = null; BufferedInputStream bis = null ...

  2. 微服务追踪SQL(支持Isto管控下的gorm查询追踪)

    效果图 SQL的追踪正确插入到微服务的调用链之间 详细记录了SQL的执行内容和消耗时间 搜索SQL的类型 多线程(goroutine)下的追踪效果 在 Kubernetes 中部署微服务后,通过 Is ...

  3. 『现学现忘』Git后悔药 — 31、reset版本回退命令总结

    目录 1.--soft回退说明 2.--mixed回退说明 3.--hard回退说明 4.总结 在Git中进行版本回退需要使用git reset命令. 以前面文章中的示例为例,当我准备在V4版本,回退 ...

  4. 【docker专栏6】详解docker容器状态转换管理命令

    docker容器有三种状态运行.停止.暂停,镜像可以创建.运行容器,镜像和容器也可以转换成tar压缩包进行存储.本文为大家介绍容器的状态转换命令及镜像创建运行容器.tar包导入导出相关的命令及使用场景 ...

  5. Linux 启动流程及相关知识

    基础知识 linux系统的组成 内核(kerner) 根文件系统(rootfs) 内核提供操作系统的功能,根文件系统包含常用的一些工具,这些工具.这些工具的运行离不开glibc库文件. 程序:二进制程 ...

  6. IDEA自定义liveTemplates(方法模板、类模板)

    IDEA自定义liveTemplates(方法模板.类模板) 前言,搞这个模板有何意义? 降低大家写方法注释的成本,统一风格.有时候不是开发同学不爱写注释,而是没有合适的载体和空间. IDEA模板设置 ...

  7. 密码学的基础:X.690和对应的BER CER DER编码

    目录 简介 BER编码 类型标识符 长度 内容 CER编码和DER编码 总结 简介 之前我们讲到了优秀的数据描述语言ASN.1,很多协议标准都是使用ASN.1来进行描述的.对于ASN.1来说,只定义了 ...

  8. 神工鬼斧惟肖惟妙,M1 mac系统深度学习框架Pytorch的二次元动漫动画风格迁移滤镜AnimeGANv2+Ffmpeg(图片+视频)快速实践

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_201 前段时间,业界鼎鼎有名的动漫风格转化滤镜库AnimeGAN发布了最新的v2版本,一时间街谈巷议,风头无两.提起二次元,目前国 ...

  9. 正则表达式实战:最新豆瓣top250爬虫超详细教程

    检查网页源代码 首先让我们来检查豆瓣top250的源代码,一切网页爬虫都需要从这里开始.F12打开开发者模式,在元素(element)页面通过Ctrl+F直接搜索你想要爬取的内容,然后就可以开始编写正 ...

  10. Java NIO全面详解(看这篇就够了)

    很多技术框架都使用NIO技术,学习和掌握Java NIO技术对于高性能.高并发网络的应用是非常关键的@mikechen NIO简介 NIO 中的 N 可以理解为 Non-blocking,不单纯是 N ...