一、前言
数据库设计及使用规范概要此规范可规避数据库设计与使用不当的问题,有效降低开发、运维、沟通、时间等成本,提高软件及平台服务的质量,是保障业务连续性的必要文档。此规范主要从数据库设计、数据库使用两方面说明,内容包含了DB 对象(数据库、表、字段、索引等)设计规则。
适用范围
本规范的适用范围为数据库开发、设计、使用的相关人员。
二、术语约定
本规范采用以下术语描述:
规则:也称为强制规范,是数据库使用时必须严格遵守的原则。
建议:使用数据库时加以考虑的原则。
说明:对此规则或建议进行必要的解释。
示例:对此规则或建议从正、反两个方面给出示例。
三、MySQL 对象规范
1. 对象命名
1.1 通用命名规则
1) 数据库对象名仅可包含小写英文字母、数字、下划线(_)三类字符,并以英文字母开头,多个字符之间用下划线(_)分隔;
2) 数据库对象(库、表、字段、索引等)禁止使用MySQL 保留字和关键字命名,MySQL 关键字参考MySQL 官档[MySQL 5.7 Keywords and Reserved Words];
【示例】
关键字:avg begin data end user server
保留字:alter and as delete insert update sql select
3) 对象名称长度不能超过32 个字符,若超过32 位,则使用简写/缩写命名;
4) 对象命名需体现业务核心含义;
5) 分库分表命名以数据库、表名开头,两位数字作为库表序号,中间使用
下划线(_)分隔:db_0[0-9]或t_x_0[0-9] 。
【示例】
分库:trans_00,trans_01 ... ,trans_99
分表:t_p_trans_00 ...,t_p_trans_99_99
1.2 数据库命名规则
1) 全平台生产数据库名不能相同、重复。
2) 数据库名要符合并体现业务含义。
3) 数据库名必须经过DBA 同意后上线使用。
1.3 表命名规则
表名建议以t_开头,第二位标识为应用标识。
【示例】
快捷支付交易表命名前缀:t_p_
清算表命名前缀:t_c_
集中处理平台:t_m_
1.4 字段命名规则
1) 同一类业务各表相同意义的字段命名及属性定义必须一致,不能存在二义性;
2) 逻辑删除标识字段名称统一为delete_flag,类型为tinyint,属性NOT NULL,值为0 或1,0 为默认值;
3) 创建时间字段命名为create_time ; 修改时间为update_time;
4) 创建人字段命名为create_by ;更新人为update_by 。
1.5 索引命名规则
1) 普通索引名称:以idx_columnnames 方式命名;
2) 唯一约束的索引名称:以uniq_columnnames 方式命名;
3) 组合索引名称:以idx_column1_column2_column3…方式命名,定义超过
32 位时采用字段名简写/缩写命名。
2. 对象设计
2.1 数据库定义规则
不指定数据库定义相关属性,但字符集必须设置为utf8。仅包含基本创建语句如下:
【示例】
CREATE DATABASE xx charset = utf8;
2.2 表设计规则
1) 表必须有主键、采用自增ID 作为主键;
【示例】
CREATE TABLE t_x(
id bigint(20) not null auto_increment,
……
primary key(id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=’xxx’;
2) 建议单实例单表字段数目小于50 个;
3) 单表中字段默认为NULL 的字段个数建议不超过6 个;
4) 索引字段属性定义必须为NOT NULL;
5) 单表中必须包含这两个时间字段:创建时间create_time、更新时间 update_time;
6) 单表3 年内数据量超过500 万必须分表;
7) 创建表定义无需添加存储引擎和字符集描述,数据库默认设置为 ENGINE=InnoDB 、CHARSET=utf8;
8) 表定义中需要添加表示其含义的中文注释,即定义COMMENT。
2.3 字段设计规则
1) 字段类型使用的优先级依次为:tinyint、int、bigint、varchar、char ; 不建议使用大字段像text、blob、varchar(xxx),其中xxx 表示500 以上等大字段,常用的字段类型有tinyint、int、bigint、datetime、date、time、char、varchar;
2) 日期类型用date,时间类型用time,时间日期类型用datetime,时间戳用timestamp;
3) 字段定义禁止使用枚举类型,使用tinyint 代替;
4) 字符类型优先使用varchar 类型,固定长字符可以使用char 类型;
5) 金额以分为单位(人民币),交易金额、交易笔数类型统一定义为bigint;
6) 字段属性优先定义为NOT NULL,并提供默认值代替DEFAULT NULL;
7) 时间字段定义默认值为CURRENT_TIMESTAMP,属性为NOT NULL;
8) 字段定义必须加上COMMENT,且状态类字段定义中必须明确列出各状态值的说明;
9) update_time 字段值应用程序不自动更新时,需定义为ON UPDATE CURRENT_TIMESTAMP;
10) 一个字段仅表示一个含义。
2.4 索引设计规则
执行时间超过0.1s 的慢SQL 需要通过使用索引或SQL 逻辑优化提升SQL 执行效率。SQL 性能优化的目标:执行计划至少要达到range 级别,consts 级别最好。
1) 单表索引个数不超过5 个,不低于1 个索引(包括主键索引);
2) 单个索引中字段数不超过5 个字段;
【说明】(Bug#26529369)单表索引信息过多可能会使数据库异常退出
3) 索引的首字段必须在相关SQL 的where 条件中;
4) 禁止在更新频繁、区分度不高的字段上建索引;
5) 定义组合索引时,将区分度高的字段作为首字段;
【说明】
这里所说的字段区分度高边界是字段所有不同值占所有值80%以上,低于此值则认为是区分度不到的字段;
6) 禁止创建重复或冗余索引;
7) 禁止对长度过长的字段建立索引,如上面所说的大字段,可创建前缀索引;
8) 禁止使用外键,容易产生死锁,应由程序实现数据约束;
9) 禁止使用force index;
3. SQL 使用
1) 禁止生产上使用存储过程、触发器、函数、视图、外键等,开源软件除外;
2) 禁止语句的Where 条件中包含恒真条件(如:1=1);
【示例】
SELECT * FROM t_x WHERE 1=1;
3) 禁止在程序代码开发中使用DDL、DCL 语句;
4) 禁止使用类型隐式转换;
5) 禁止使用以%开头的模糊查询;
【说明】对于配置管理库,总数据量不超过10000 行的表,查询不频繁情况下(如1 天100 次以内),可以使用,但要保证SQL 性能达到上述优化目标。
6) 禁止应用通过数据库实现业务层sequence 功能;
7) 禁止SQL 或程序中使用db.table ;建议通过use db 或配置数据库的方式切换数据库;
8) INSERT 语句必须指定需要赋值的字段名;
9) 禁止在SQL 中添加Hint;
10) 线上业务库禁止使用join 连接查询;
11) 建议关键字大写,表名、字段名小写;
【示例】
SELECT id,name FROM t_x ;
12) 不建议使用负向查询,如where 条件中包含not in , not like ,!= 等;
【反例】
SELECT id,name FROM t_x WHERE id!=xx;
13) 查询数据时需给出明确的字段,禁止程序代码中使用SELECT *;
14) 禁止对索引字段进行数学运算和函数运算。
四、数据库安全
1. 认证安全
1.1 用户安全
1) 用户的命名应符合业务含义,且和线上已有用户不能重名;
2) 用户命名只能包含小写英文字母和下划线,且不能以下划线开头;
3) 线上不同业务间不能使用同一用户;
4) 同一个用户名的密码必须相同;
5) 线上用户的命名必须经过DBA 同意后使用。
1.2 生产权限规则
1) 生产环境中应用操作数据库默认权限是INSERT、UPDATE、SELECT;
授权范围是各业务数据库;DELETE 及DDL 等权限在一些特殊的情况下可以用,但需DBA 审核决定;
2) 线上同一个用户对同一业务数据库的操作权限必须一致。
1.3 密码安全
1) 禁止明文公开显示数据库用户密码;尤其是应用层在配置文件,WIKI,代码等公开地方不允许使用明文密码;
2) 所有数据库应用账号密码长度为12 位,其中包含大小写字符、数字;且由数据库自动生成后发送开发使用;
3) 禁止应用通过数据库客户端直接登录访问生产数据库;
4) 密码复杂度要求
2. 数据安全
2.1 数据一致性
主备间默认配置MySQL 强半同步,同城备和异地备默认为异步复制。针对数据一致性要求高的业务,建议通过测试,采用MySQL 双1 配置(sync_binlog=1、innodb_flush_log_at_trx_commit=1);针对数据一致性要求极高的业务,考虑从应用层面保障数据一致性。
2.2 数据恢复
1) 数据恢复方式
基于主库binlog 数据同步恢复,binlog_row_image 为full 格式使用备份文件恢复数据库数据本地备或同城备故障,同城备或异地备都会自动级联上
2) 数据恢复常用场景
故障机恢复
数据不一致
数据库binlog 异常
同步中断
...
2.3 历史数据归档及清理
采用分库分表架构的库表,需提前与DBA 沟通历史数据清理方案,避免表过大,影响线上业务。清理方案需同DBA 商议确定,目前数据库组线上历史数据自动清理的要求如下:
1) 数据清理前提
必须分表且单表数据量超过500 万
历史数据要先归档到大数据
分表表结构设计要经过DBA 和大数据组的同意
2) 业务需要提供以下信息
需要清理的表清单
表中历史数据保存时间
清理历史数据对现有业务的影响
五、应用客户端访问
当客户端连接到MySQL 服务器时,服务器首先需要对其进行认证,认证通过连接成功,当执行某个SQL 操作时,MySQL 会进一步检查该用户是否有执行权限。
客户端访问数据库限制:
1) 跨机房间带宽较长,无法保障数据一致性,不允许应用跨机房访问数据库;
2) 数据库连接池配置建议连接数初始值在5 到10 之间,最大值20 到 30 之间;考虑大促连接风暴,建议大促前进行连接预热;
3) 数据库单实例支持最大连接为8000,建议平时最大连接数不超过总数的一半4000,连接虚机数据库建议不要超过2000;
4) 应用访问数据库空闲连接超时时间为8 小时;
5) 读写都连接数据库主库操作,大数据采取优先抽取本地备库,本地备库故障,联系dba 选择同城备或选择异地备库;
6) 通过配置DNS 域名连接数据库。