1. 规范背景与目的
MySQL数据库与 Oracle、 SQLServer 等数据库相比,有其内核上的优势与劣势。我们在使用MySQL数据库的时候需要遵循一定规范,扬长避短。本规范旨在帮助或指导产品,研发等技术人员做出适合线上业务的数据库设计。在数据库变更和处理流程、数据库表设计、SQL编写等方面予以规范,从而为公司业务系统稳定、健康地运行提供保障。
2. 设计规范
2.1 数据库设计
2.1.1 库名
库的名称必须控制在32个字符以内,相关模块的表名与表名之间尽量提现join的关系,如user表和user_login表。
库的名称格式:业务系统名称_子系统名,同一模块使用的表名尽量使用统一前缀。
一般分库名称命名格式是库通配名_编号,编号从0开始递增,比如wenda_001以时间进行分库的名称格式是“库通配名_时间”
创建数据库时不要显式指定字符集,所有生产库字符集默认都是utf8mb4。创建数据库SQL举例:create database db1;
2.1.2 表结构
表和列的名称必须控制在32个字符以内,表名只能使用字母、数字和下划线,一律小写。
表名要求模块名强相关,如师资系统采用”sz”作为前缀,渠道系统采用”qd”作为前缀等。
创建表不要显式指定字符集,目前我们所有数据库字符集统一为:utf8mb4。
创建表不要显式指定表存储引擎类型,默认为InnoDB。当需要使用其他存储引擎时,必须通过DBA审核才能在生产环境中使用。因为Innodb表支持事务、行锁、宕机恢复、MVCC等关系型数据库重要特性,为业界使用最多的MySQL存储引擎。而这是其他大多数存储引擎不具备的,因此首推InnoDB。
建表必须有comment。
建表时关于主键:
6.1强制要求主键为id,类型为int unsigned或bigint unsigned,且为auto_increment
6.2标识表里每一行主体的字段不要设为主键,需要设置为其他字段如user_id,order_id等,并建立unique key索引。因为如果设为主键且主键值为随机插入,则会导致innodb内部page分裂和大量随机I/O,性能下降。
所有表必须有行数据的创建时间字段create_time和最后更新时间字段edit_time,便于排查问题以及数据增量抽取。
表中所有字段必须都是NOT NULL属性,业务可以根据需要定义DEFAULT值。
8.1因为使用NULL值会存在每一行都会占用额外存储空间、数据迁移容易出错、聚合函数计算结果偏差等问题。
8.2字符型数据类型建议默认值为“(空字符串);
8.3日期时间型数据类型默认值建议为‘1000-01-01 00:00:00’;
表里的blob、text等大字段需要垂直拆分到其他表里,仅在需要读这些对象的时候才去select,并使用uk进行关联两表。
反范式设计:把经常需要join查询的字段,在其他表里冗余一份。如user_name属性在user_account,user_login_log等表里冗余一份,减少join查询。
中间表用于保留中间结果集,名称必须以“_tmp”/“_temp”结尾。备份表用于备份或抓取源表快照,名称必须以“_bak”/“_bake”结尾。