- 命名规范
- 数据库基本设计规范
- 数据库字段设计规范
- 索引设计规范
- 常见索引列建议
- 数据库开发规范
- 数据库操作行为规范
1.所有数据库对象名称必须使用小写字母并用下划线分割 2.禁止使用 MySQL
保留关键字,如果表名中包含关键字查询时,需要使用单引号括起来 3.见名识意 4.名称不要超过 32
个字符 5.临时库表以 tmp_
为前缀并以日期为后缀,备份表以 bak_
为前缀并以日期为后缀 6.所有存储相同数据的列名和列类型必须一致,一般作为关联列,如果查询时关联列类型不一致会自动进行数据类型隐式转换,会造成列上的索引失效,导致查询效率降低 7.列名不要带上表名,例如,student
表中的列 id
,name
等,不要命名成 student_id
,student_name
1.没有特殊要求下,所有表必须使用 innodb 存储引擎 支付事务、行级锁、更好的恢复性、高并发下性能更好
2.数据库和表的字符集统一使用 utf8 统一字符集可以避免由于字符集转换产生的乱码,不同的字符集进行比较前需要进行转换会造成索引失效
3.所有表和字段都需要添加注释 使用 comment 从句添加表和列的备注进行数据字典的维护
4.尽量控制单表数据量的大小,建议控制在500万以内 过大的数据量,在修改表结构、备份、恢复都会有很大的问题。
5.谨慎使用分区表 分区表在物理上表现为多个文件,在逻辑上表现为一个表,跨分区查询效率可能更低,建议采用物理分表的方式管理大数据
6.尽量做到冷热数据分离,减小表的宽度 MySQL 限制每个表最多存储4096列,并且每一行数据在大小不能超过65535字节
7.减少磁盘IO 保证热数据的内存缓存命中率,避免读入无用的冷数,经常一起使用的列放到一个表中避免更多的关联操作。
8.禁止在表中建立预留字段 无法确认存储的数据类型,对预留字段类型的修改会对表进行锁定
9.禁止在数据库中存储图片,文件等大的二进制数据 IO操作耗时,通常存储于文件服务器,数据库只存储文件地址信息
10.禁止在线上做数据库压力测试
11.禁止从开发环境、测试环境直接连接生产环境数据库
数据库字段设计规范1.优先选择符合存储需要的最小的数据类型 字段大,建立索引空间大,IO次数多,索引性能差
2.将字符串转换成数字类型存储 例如,IP地址在插入数据前先用 inet_aton() 函数把 IP 地址转为整型,节省空间,显示数据时使用 inet_ntoa() 函数把二进制整数转成 IP 地址字符串显示即可。
3.对于非负的整数,建议使用无符号整数类型存储 例如,自增 ID,要优先使用无符号整型来存储,无符号相对于有符号可以多出一倍的存储空间
SIGNED INT:-2147483648~2147483647
UNSIGNED INT:0~4294967295
4.VARCHAR(N) 中的 N 代表的是字符数,而不是字节数 使用 UTF8 存储 255 个汉字 varchar(255)=765 个字节。过大的长度会消耗更多的内存,避免使用 text、blob 数据类型,最常见的 text 类型可以存储 64K 的数据,可以分离到单独的扩展表中。 MySQL 内存临时表不支持 text/blob 大数据类型,如果查询中包含这样的数据,在排序等操作时,就不能使用内存临时表,必须使用磁盘临时表进行,MySQL 还要进行二次查询,会使 SQL 性能变得很差,不需要 text 类型的列的数据时不要对该列进行查询。 text/blob 类型只能使用前缀索引,并且text列上是不能有默认值的。
5.避免使用 enum 类型 修改 enum 值需要使用alter语句; enum 类型的order by 操作效率低,需要额外操作; 禁止使用数值作为enum的枚举值。
6.尽可能把所有列定义为 not null 索引 null 列需要额外的空间来保存,所以要占用更多的空间; 进行比较和计算时要对 null 值做特别的处理。
7.使用 timestamp
4 个字节 或 datetime
类型 8 个字节存储时间 TIMESTAMP
存储的时间范围 1970-01-01 00:00:01 ~ 2038-01-19-03:14:07
; TIMESTAMP
占用 4 字节和 INT
相同,但比 INT
可读性高; 超出 TIMESTAMP
取值范围的使用 DATETIME
类型存储。
8.同财务相关的金额数据必须使用 decimal 类型
非精准浮点:float,double 精准浮点:decimal
Decimal 类型为精准浮点数,在计算时不会丢失精度。占用空间由定义的宽度决定,每 4 个字节可以存储 9 位数字,并且小数点要占用一个字节。可用于存储比 bigint 更大的整型数据。
索引设计规范1.限制每张表上的索引数量,不超过 5 个,索引可以增加查询效率,同样也会降低插入和更新的效率,有些情况下会降低查询效率
因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估,以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能。
2.禁止给表中的每一列都建立单独的索引
使用联合索引查询
每个索引组织表 innodb 必须有个主键–数据的存储的逻辑顺序和索引的顺序是相同的,每个表都可以有多个索引,但是表的存储顺序只能有一种 innodb 是按照主键索引的顺序来组织表的。
3.不要使用更新频繁的列作为主键
4.不要使用 uuid md5 hash 字符串列作为主键
无法保证数据的顺序增加
6.主键建议使用自增ID值
常见索引列建议1.出现在 select update delete 语句的 where 从句中的列
2.包含在order by group by distinct 中的字段
3.多表join的关联列
4.建立联合索引效果更好
5.索引列的顺序 区分度最高的放在联合索引的最左侧 ,区分度 = 列中不同值的数量 / 列的总行数 尽量把字段长度小的列放在联合索引的左侧
6.避免建立冗余索引和重复索引
重复索引示例:primary key(id)、index(id)、unique index(id) 冗余索引示例:index(a,b,c)、index(a,b)、index(a) 7.优先考虑覆盖索引 就是包含了所有查询字段(where select order by group by )的索引 避免lnnodb表进行索引的二次查询
8.尽量避免使用外键约束 但要在表与表之间的关联键上建立索引,外键建议在业务端实现参照完整性 外键会影响父表和子表的写操作从而降低性能
数据库开发规范1.建议使用预编译语句进行数据库操作 减少编译所需要的时间; 还可以解决动态 sql 所带来的 sql 注入问题; 只传参数,比传递 sql 语句更高效,相同语句可以一次解析,多次使用,提高处理效率。
2.避免数据类型的隐式转换
3.充分利用表上已经存在的索引 避免使用双 % 号的查询条件
4.一个 sql 只能利用到复合索引中的一列进行范围查询 例如,有 a、b、c 列的联合索引,在查询条件中有 a 列的范围查询,则在 b、c 列上的索引将不会被用到,在定义联合索引时,如果 a 列要用到范围查找的话,就要把 a 列放到联合索引的右侧 5.使用 left join 或 not exists 来优化 not in 操作 因为 not in 也通常会使用索引失效。
6.数据库设计要充分考虑扩展性
程序连接不同的数据库使用不同的账号跨库查询 为数据库迁移和分库分表留出余地 降低业务耦合度
7.禁止使用 select *
,应该使用 select column1, column2,...
查询
8.禁止使用不含字段的 insert into
语句
9.避免使用子查询,可以把子查询优化为 join 操作 子查询结果无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引。
10.避免使用 JOIN 关联太多的表 关联缓存大小可以由 join_buffer_size 参数进行设置,最多允许关联 61 个表,建议不超过 5 个。
11.减少同数据库的交互次数
批量执行脚本语句,可以提高处理效率
12.对列的值进行 or 判断时,使用 in 代替 or
可以更有效的利用索引,or 很少能利用到索引; in 的值不要超过 500 个。
13.禁止使用 order by rand() 进行随机排序
14.where 从句中禁止对列进行函数转换和计算
因为无法使用索引
15.在明显不会有重复值时使用 union all 而不是 union
union 会把两个结果集的所有数据放到临时表中后再进行去重操作,union all 不会对结果集进行去重操作
16.拆分复杂的大 SQL 为多个小 SQL
大 SQL 逻辑上比较复杂,需要占用大量 CPU 进行计算; MySQL 一个 SQL 只能使用一个 CPU 进行计算,拆分成多个小 SQL 语句可能通过并行执行来提高处理效率
数据库操作行为规范1.删除匿名账户,并且给 root 账户设置登录密码
刚安装好的 MySQL 包含一个含空密码的 root 帐户和两个匿名帐户,这是很大的安全隐患,对于一些重要的应用我们应将安全性尽可能提高,所以我们要把匿名帐户删除,并且为 root 帐户设置密码,可用如下命令进行:
mysql> use mysql;
mysql> delete from user where user="";
mysql> update user set password=password('newpassword') where user='root';
2.超100万行的批量写操作,要分批多次进行操作
大批量修改数据,一定是在一个事务中进行的,这就会造成表中大批量数据进行锁定,从而导致大量的阻塞
3.对于大表使用 pt-online-schema-change 修改表结构
避免大表修改产生的主从延迟,避免在对表字段进行修改时进行锁表 pt-online-schema-change 首先建立一个与原表结构相同的新表,并且在新表上进行表结构的修改,然后再把原表中的数据复制到新表中,并在原表中增加一些触发器,把原表中新增的数据也复制到新表中,所有数据复制完成之后,把新表命名成原表,并把原表删除掉。
4.禁止为程序使用的账号赋予 super 权限
对于程序连接数据库账号,遵循权限最小原则。
在进行开发和实际应用中,用户不应该只用 root 用户进行连接数据库,虽然使用 root 用户进行测试时很方便,但会给系统带来重大安全隐患,也不利于管理技术的提高。我们给一个应用中使用的用户赋予最恰当的数据库权限。如一个只进行数据插入的用户不应赋予其删除数据的权限。