1. 基础规范


(1) 所有环境的MySQL版本使用5.6社区版,64位版本; (2) 使用INNODB存储引擎; (3) 数据库字符集默认为utf8,字符集默认校验规则为utf8_general_ci; (4) 所有表、字段都需要添加注释; (5) 单表数据量控制在2000W以内; (6) 隔离线上和线下,禁止线下直接连接线上库,禁止在已上线库上做压力测试;

2. 命名规范


(1) 库名、表名、字段名建议不超过32个字符,可用单词简写,但须见名之意; (2) 库名、表名、字段名须使用小写字母,“_”分割。 (3) 库名、表名、字段名禁止使用MySQL保留字; (4) 临时库、表名建议以tmp为前缀,并以日期为后缀; (5) 备份库、表建议以bak为前缀,并以日期为后缀; (6) 使用时间分表,表名后缀建议使用特定格式,比如按年分表user_2016按月分表user_201602、按日分表user_20160209;

3. 库、表、字段设计规范


(1) 控制单库的表数量,建议在400张表左右; (2) 表字段数少而精,字段数量上限控制在50个; (3) 字段数据类型长度选择遵守够用最小原则; (4) 拆分大字段和访问频率低的字段,分离冷热数据,拆分成两张表; (5) 用HASH进行散表,表名后缀使用十进制数,下标从0开始; (6) 采用合适的分库分表策略,例如十库百表等; (7) 展示型价格字段可使用FLOAT和DOUBLE类型存储,用于计算的价格字段建议用DECIMAL类型存储; (8) 所有字段建议均定义为NOT NULL,NULL字段难于查询优化,NULL字段的索引需要额外空间; (9) 使用UNSIGNED存储非负整数; (10) 使用VARBINARY存储大小写敏感的变长字符串; (11) 禁止在数据库中存储明文密码,把密码加密后存储; (12) 存储ip最好用int存储而非char(15)或者varchar(15); (13) 存储精确到秒的时间建议使用DATETIME,DATETIME和TIMESTAMP都是精确到秒,优先选择DATETIME,因为TIMESTAMP只有4个字节,存储的最大值为2038年的某一天,而DATETIME 占用8个字节。 (14) 尽量使用tinyint类型代替enum类型; (15) 尽可能不使用TEXT/BLOB类型,varchar的性能会比TEXT/BLOB高很多,实在避免不了TEXT/BLOB,请拆分表; (16) 数据库中禁止存储大文件,或者照片,可以将大对象放到磁盘上,数据库中存储它的路径;

4. 索引规范

1、索引命名:


非唯一索引建议以 idx_字段1_字段2命名,唯一所以建议以unq_字段1_字段2命名,索引名称建议全部小写;

2、索引的数量要控制:


(1) 单张表中索引数量尽量不超过5个,避免过多索引影响update、insert、delete的性能; (2) 单个索引中的字段数尽量不超过5个; (3) 对字符串使用前缀索引,前缀索引长度不超过30个字符,短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作; (4) 建议优先考虑前缀索引,必要时可添加伪列并建立索引,多条字段重复的语句,要修改语句条件字段的顺序,为其建立一条联合索引,但也避免冗余索引;

3、主键准则:


(1)建议每张表都要有自增主键id int(11) unsigned,且与业务无关,not null  auto_increment; (2) 不使用更新频繁的列作为主键; (3) 尽量不选择字符串列作为主键; (4) 不使用UUID MD5 HASH这些作为主键; (5) 默认使用非空的唯一键作为主键;

4、多表JOIN的字段注意以下:


(1) 区分度最大的字段放在前面; (2) 核心SQL优先考虑覆盖索引; (3) 避免冗余和重复索引; (4) 索引要综合评估数据密度和分布以及考虑查询和更新比例;

5、索引禁忌:


(1) 不在低基数列上建立索引,例如“性别”,“类型”等字段; (2) 不在索引列进行数学运算和函数运算,会导致索引失效而进行全表扫表;

6、尽量不使用外键:


(1) 外键用来保护数据一致性和完整性,由应用端实现; (2) 对父表和子表的操作会相互影响,降低可用性;

7、索引字段的默认值尽量不为NULL,要改为其他的默认值或者空串;

8、能使用唯一索引尽量使用唯一索引,提高查询效率;

5. SQL规范


(1) SQL语句尽可能简单,大的SQL想办法拆成小的sql语句,可充分利用多核CPU; (2) 事务要简单,整个事务的时间长度不要太长; (3) 尽量避免使用触发器、函数、存储过程; (4) 降低业务耦合度,为sacle out、sharding留有余地; (5) 避免在数据库中进行数学运算(MySQL不擅长数学运算和逻辑判断); (6) 禁止用select *,查询哪几个字段就select这几个字段,减少cpu、IO和网卡的压力; (7) in里面数字的个数建议控制在1000以内; (8) Limit分页注意效率,Limit越大,效率越低; (9) 避免使用大表的join; (10) 使用group by 分组、自动排序; (11) 对数据的更新要打散后批量更新,不要一次更新太多数据; (12) 减少与数据库的交互次数; (13) SQL语句不可以出现隐式转换,比如 select id from tb where id=’1’; (14) 在SQL语句中,禁止使用前缀是%的like,无法使用索引; (15) 不使用负向查询,如not in和%前缀模糊查询,导致全表扫描; (16) 关于分页查询:程序里建议合理使用分页来提高limit效率,offset较大要配合子查询使用; (17) 禁止使用order by rand(); (18) 禁止单条SQL语句同时更新多个表,易造成死锁; (19) 禁止在应用程序端显式加锁;

6. 流程规范


(1) 不在业务高峰期批量更新、查询数据库或者导入导出数据; (2) 所有的建表操作需要提前告知,建议在建表的时候,添加对应列的索引; (3) 所有的改表结构、加索引操作都需要将涉及到所改表的查询SQL发工单提前告知DBA等相关人员,核心业务表或者大数据量表需要在业务低峰期进行; (4) 批量导入、导出数据建议提前通知DBA,并在业务低峰期进行; (5) 禁止有super权限的应用程序账号存在; (6) 推广活动前通知DBA即将到来的流量评估;