MYSQL DB规范

  1. 命名规范
    库名、表名、字段名必须使小写字符,并采用下划线分割
    库名、表名、字段名禁止超过32个字符。须见名知意
    库名、表名、字段名禁止使用MySQL保留字
    临时库、表名必须以tmp为前缀,并以日期为后缀
    备份库、表必须以bak为前缀,并以日期为后缀
    例子:
    create table TTT (insert int(10) not null …)
    create table abc_1202 …
    alter table t add index idx_uid_mid_time(uid,mid,time)
    alter table t add index idx_uid(uid,mid,time) ->NO
    tmp_test01_0704 ->NO bak_test01_20130704web

  2. 基础规范
    使用INNODB存储引擎
    表字符集使?UTF8
    全部表都须要添加注释
    单表数据量建议控制在5000W之内 ->500W内性能最佳
    不在数据库中存储图片、文件件等大数据
    禁止在线上作数据库压力测试
    禁止从测试、开发环境直连数据库数据库

  3. 库表设计
    慎用分区表
    拆分大字段和访问频率低的字段,分离冷热数据
    用HASH进行散表,表名后缀使十进制数,下标从0开始
    按日期时间分表需符合YYYY[MM][DD][HH]格式
    采用合适的分库分表策略。例如千库十表、十库百表等 、
    例子:
    comment_20120815
    comment_20120816
    comment_120817
    user_39
    user_3A
    user_3B
    user_3C网络

  4. 字段设计
    尽量不使用TEXT、BLOB类型
    用DECIMAL代替FLOAT和DOUBLE存储精确浮点数
    Simple is good
    将字符转化为数字
    使用TINYINT来代替ENUM类型
    Generosity can be unwise
    存储 “hello”时VARCHAR(5) VS VARCHAR(200)
    The best strategy is to allocate only as much space as you really need.
    ENUM(‘Mercury’, ‘Venus’, ‘Earth’) numbers ENUM(‘0’,’1’,’2’)
    存储index,而不是字符串
    枚举值改变会致使DDL
    Avoid null if possible
    可为NULL的列影响索引统计数据生成
    可为NULL的列加索引会占用额外空间
    全部字段均定义为NOT NULL
    Smaller is usually better
    使用UNSIGNED存储非负整数
    INT类型固定占用4字节存储
    使用timestamp存储时间
    使用INT UNSIGNED存储IPV4
    使用VARBINARY存储大小写敏感的变长字符串
    禁止在数据库中存储明文密码app

  5. 索引规范
    索引的用途
    去重
    加速定位
    避免排序
    覆盖索引
    索引数量控制
    单张表中索引数量不超过5个
    单个索引中的字段数不超过5个
    对字符串使用前缀索引,前缀索引长度不超过8个字符
    建议优先考虑前缀索引,必要时可添加伪列并创建索引
    主键准则
    表必须有主键
    不使用更新频繁的列
    尽可能不选择字符串列
    不使用UUID MD5 HASH
    默认使非空的惟一键
    建议选择自增或发号器
    重要的SQL必须被索引
    区分度最大的字段放在前面
    核心SQL优先考虑覆盖索引
    避免冗余和重复索引
    索引不是越多越好
    综合评估数据密度和分布
    考虑查询和更新比例
    索引是一把双刃剑:下降插入和更新速度,占用磁盘空间
    索引禁忌
    不在低基数列上创建索引,例如“性别”
    不在索引列进行数学运算和函数运算
    尽可能不使用外键
    外键用来保护参照完整性,可在业务端实现
    对父表和子表的操做会相互影响,下降可用性
    INNODB自己对online DDL的限制
    不使用%前导的查询,如like “%ab”
    不使用负向查询,如not in/like
    没法使用索引,致使全表扫描
    全表扫描致使bufer pool利用率下降
    尺有所短,寸有所长,换一种工具试试!svg

  6. SQL设计
    避免使用存储过程、触发器、UDF、events等
    让数据库作最擅长的事
    下降业务耦合度,为scale out、sharding留有余地
    避开BUG
    避免使用大表的JOIN
    MySQL最擅长的是单表的主键/二级索引查询
    JOIN消耗较多内存,产生临时表
    避免在数据库中进行数学运算
    MySQL不擅长数学运算和逻辑判断
    没法使用索引
    md5()/order by rand()
    select … where to_days(current_date) - to_days(date_col)<=10
    select … where date_col>=date_sub(current_date, interval 10 day)
    select … where date_col>=date_sub(‘2013-08-17’, interval 10 day)
    select … where date_col>=‘2013-08-07’
    数据库是有状态的服务,调整代码部署更灵活、简单、高效!
    减小与数据库的交互次数
    INSERT … ON DUPLICATE KEY UPDATE
    REPLACE INTO、INSERT IGNORE 、INSERT INTO VALUES(),(),()
    UPDATE … WHERE ID IN(10,20,50,…)
    合理的使用分页
    限制分页展开的页数
    只能点击上一页、下一页
    采用延迟关联(join的延迟)
    拒绝大SQL,拆分红小SQL
    充分利用QUERY CACHE
    充分利用多核CPU
    使用in代替or,in的值不超过1000个 (所在列没有索引的状况差异巨大)
    禁止使用order by rand()
    使用EXPLAIN诊断,避免生成临时表
    用union all而不是union(union会多作一次去重的操做)
    程序应有捕获SQL异常的处理机制
    禁止单条SQL语句同时更新多个表
    不使用select *
    消耗CPU和IO、消耗网络带宽
    没法使用覆盖索引
    减小表结构变动带来的影响
    由于大,select/join 可能生成临时表
    select * from opp where phone=‘12345678’ or phone=‘234234234’
    select * from opp where phone in (’12345678’, ‘234234234’)
    select * from app where phone=‘010-88886666’ or cellphone=‘18618111111’
    select * from opp where phone=’010-88886666’
    union all select * from opp where cellphone=’ 18618111111’函数

  7. 行为规范
    批量导入、导出数据必须提早通知DBA协助观察
    禁止在线上从库执行后台管理和统计类查询
    禁止有super权限的应用程序帐号存在
    产品出现非数据库致使的故障时及时通知DBA协助排查
    推广活动或上线新功能必须提早通知DBA进行流量评估
    数据库数据丢失,及时联系DBA进行恢复
    对单表的屡次alter操做必须合并为一次操做
    不在MySQL数据库中存放业务逻辑
    重要项目的数据库方案选型和设计必须提早通知DBA参与
    对特别重要的库表,提早与DBA沟通肯定维护和备份优先级
    不在业务高峰期批量更新、查询数据库
    提交线上建表改表需求,必须详细注明全部相关SQL语句
    良好的线上环境须要你们共同的努力! 工具