mysql基础~开发规范

一 简介:今天咱们来聊聊如何针对开发进行规范和培训

二 目的:为了能够更好的在源头进行规范研发人员对于mysql的应用,从开始就进行规范,能够减少以后一系列的问题
三  阶段:
   1 创建表进行规范(请参考创建表规范)
   2 查询语句和索引(请参考索引失效场景和查询建议)
   3 DML语句规范(请参考DML语句规范)
   4 业务场景并发和增长预算(请参考 业务场景估算)
四  创建表规范(create)

  1 表级别
     1 主要采用innodb引擎+utf8/uft8-mb4以上字符集,不要为单列指定字符集,不要采用memory引擎
     2 主键要采用自增ID,对于大表,建议使用bigint,业务需求可以采用唯一索引进行约束
     3 不允许使用外键,不能使用集合,枚举.位图类型
     4 不要使用事件.存储过程,触发器等消耗mysql性能的功能
     5 建表语句不要包含除引号外的其他特殊符合,尤其是反引号
    6 表名和字段名一律强制用小写,防止有大小写识别的问题
    7 表和字段名不要触及到任何mysql的关键字,创建表最好以业务命名,不允许不同库同表命名相同

    8 针对表的数据量一定要提前进行规划好,定期拆分,避免出现问题
 2 列级别
    1 列必须需要有comment说明,默认值最好不要default not
    2 最好不使用blob/text类型,对于范围要求较高的数值,采用UNSIGNED(无符号型)
    3 对于时间类型的选择 建议采用 datetime,开销较小,时间范围大,不可以设置系统默认值
    4 对于varchar长度设计要根据业务需求,不能设置太大,否则有可能不能建立和适用索引全部
    5 对于精度字段的处理,建议选择decimal,也可以使用bigint进行程序二次计算
    6 对于特殊场景应采用通用解决办法,比如存储IP采用int类型,然后用函数进行转化
 3 索引级别
   1 每张表最好不多于5个索引,因为维护索引也会加重负担
   2 不要在区分度较低并且更新频率高的字段建立索引,高并发下可能出现死锁问题
   3 建立联合索引要符合最左原则,区分度从高到低
   4 对于不在应用的索引要提示进行删除维护
   5 建立索引要统一以idx_开头命名,实现统一规范
   6 针对类似业务的多个sql,选取相同的部分条件建立索引,以达到一索引多用的效果 

五  查询场景(select)

  1 索引相关

       1 索引失效场景 

          1 在索引列进行数学运算和函数运算
          2 使用%前导的查询
          3 使用反向查询,如not in / not like
          4 使用不等值查询,如=! <>
          5 日期DATE_FORMAT使用sysdate()函数
          6 字符串查询没有带引号,发生隐式转换
          7 多表join,表的字符集不同(比如utf8和utf8_mb4) 会使连接字段的索引失效,因为会发生函数字符集转化
          8 不符合联合索引最左原则
          9 mysql优化器认为利用索引扫描的成本高于全表扫描,不会利用索引
          10 没有任何利用索引的条件查询
          11 查询的数据量到达表数据量的至少1/3
          12 表本身元数据不准确的情况下会导致explain判断失误
     2 语句建议

         1 禁止使用order by rand()
         2 禁止使用select * from 
         3 统计表总数要使用select count(*)/select count(1)   
         4 禁止where无条件,条件无索引 
         5 优化分页查询,对于数据量大的分页查询,根据业务判断是否能优化 
         6 多表联查的连接字段,必须要加索引
         7 尽量减少多表联查的连接表数量,将大sql拆分为多个小sql
        8 对于不再使用的task查询语句,要尽早下线或者降低查询频率
        9 尽量将计算交与程序,而不是利用mysql内部函数,消耗数据库的资源
       10 尽量提前做好数据库的读写分离,将查询转移到从库,减少主库压力
       11 对于慢查询语句必须尽快优化,防止慢查询堆积

六 事务控制(DML语句)

  1 事务建议
     1 对于事务操作,尽量都根据索引进行操作,最好是主键
     2 针对大事务操作,要将大事务拆分为小事务
          1 最好按照主键作为拆分条件,针对delete/update操作,
          2 values进行合并,针对insert操作
     3 对于特殊事务处理,要在业务低峰期做
          1 insert into a select b b是要加锁的,并非快照读
          2 update a where id in (select b) b同样是要对符合条件的加锁
2 架构设计
     1 在程序上线时期就要做好读写分离,防止因为业务增长导致的主库压力
     2 redis 作为缓存架构,采用 redis 缓存数据库减少直接操作mysql的次数,减轻主库的压力
     3 ES提供mysql类似查询功能, 减少直接操作mysql的次数,减轻主库的压力
     4 在业务增长导致的热数据增长时做好库表常规拆分,减少单台DB的压力,防止影响业务,方式就是做好业务增长量估算
     5 对于分库分表跨机器操作,建议采用类似sharding-jdbc的程序中间件进行规划拆分库表
     6 程序一定要有重连机制,否则不能保证mysql故障切换后程序业务的可用性

七 锁相关
    1 将多个同表的DDL语句合并成一条语句进行执行
     2 避免死锁的措施  
        1 对于insert的单事务语句并发,1 减少唯一性列重复值的插入2 去掉唯一性的检测
        2 对于update的单事务语句并发,1 尽量减少并发线程数量 2 尽量改成按照主键更新,只锁定对应行 3 改造业务去掉更新
        3 对于混合事务语句并发 1 调整加锁顺序 2 减少并发线程数量
   3 避免锁等待的措施
      1 尽量按照主键/唯一键更新,只扫描需要的主键行 防止由 并发变成串行


小建议: 利用inception在测试环境,inception本身自带很多审核规范,很有用.

原文地址:https://www.cnblogs.com/danhuangpai/p/9396936.html