数据库设计规范

**所有数据库对象名称必须使用小写字母并用下划线分割
(原因mysql数据库是一个文件,在windows系统里面是不区分大小写的但linux下系统严格)**

所有数据库对象名称禁止使用、mysql保留关键字

select id,username,fron,age from tb_user 这种方式 MySQL是无法识别的

如果使用 select id,username,from,age from ta_userfrom 加上from带表 当正常字符

http://dev.mysql.com/doc/refman/5.7/en/keywords.html
此链接是mysql数据库的关键词列表

数据库对象的命名要做到见名知意

例如 用户数据库 mc_userdb
用户数据表 user_account

临时库表必须以tmp为前缀并以日期为后缀

备份库,备份表必须以bak为前缀以日期为后缀

所有存储相同数据的列名和列类型必须一致

示例1

关联表的 字段的数据类型要一致

数据库基础设计规范

所有表必须使用Innodb存储引擎 5.6以后的默认引擎

数据库和表的字符集统一使用UTF8,如果表情扩展用utf8m4(
统一字符集可以避免有字符集转换产生的乱码 ,
mysq中的UTF8字符集汉子点3个字节,ASCII占用1个字节)

所有表和字段都需要添加注释
使用comment 从句添加表和列的备注
从一开始就进行数据库字典的维护

尽量控制表标数据量的大小,建议控制在500万行以内
500万并不是mysql数据库的限制,mysql最多可以存储多少万数据呢?
这种限制区别于存储设置和文件系统。

可以用历史数据归档,分库分表等手段来控制数据量的大小。

谨慎使用mysql分区表
分区表在物理上表现为多个文件,在逻辑上表现为一个表

谨慎选择分区建,跨分区查询效率可能更低

什么是分表?

分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表,我们可以称为子表,每个表都对应三个文件,MYD数据文件,.MYI索引文件,.frm表结构文件。这些子表可以分布在同一块磁盘上,也可以在不同的机器上。app读写的时候根据事先定义好的规则得到对应的子表名,然后去操作它。

什么是分区?

分区和分表相似,都是按照规则分解表。不同在于分表将大表分解为若干个独立的实体表,而分区是将数据分段划分在多个位置存放,可以是同一块磁盘也可以在不同的机器。分区后,表面上还是一张表,但数据散列到多个位置了。app读写的时候操作的还是大表名字,db自动去组织分区的数据

分区分表的文章介绍:https://www.2cto.com/database/201503/380348.html

建议采用物理分表的方式管理大数据(应用开发难度高,例如用uuid分表等)

尽量做到冷热数据分离,减少表的宽度(mysql限制最多能存储4096列)。

热数据也就是常用的数据,冷数据反之。

减少磁盘IO,保证热数据库的内存缓存命中率
利用更有效的利用缓存,避免读入无用的冷数据(例如select *)
经常一起使用的列放在一个表中。

禁止在表中建立预留字段

**原因:预留字段的命名很难做到见名知意,预留字段无法确认存储的数据类型,所以无法选择合适的类型。对预留字段类型的修改,会对表进行锁定。
禁止在数据库中存储图片,文件等二进制数据**

原因:文件二进制字符非常大,数据库增长特别快,一般放到文件服务器里面,

禁止在线上做数据库压力测试

禁止从开发环境,测试环境直连生产环境

索引设计规范

索引对数据库的查询性能来说的非常重要的,不要滥用索引。

限制每张表上的索引数量,建议单张表索引不超过5个。

索引并不是越多越好!索引可以提高效率同样可以降低效率
索引可以增加查询效率,但同样一会降低插入和更新的效率

强烈建议每个Innodb表必须有一个主键

不使用更新频繁的列作为主键,不适用多列主键

高级DBA 说 innodb是组织索引表结构,
尽量不使用UUID,MD5,HASH,字符列作为主键,因为索引的顺序无法保证先后大小顺序,
索引造成多余的cpu开销。

面试上会问? 在数据表设计中那写列上索引,常见索引列建议

select ,update,delete语句的where从句中的列 包含在order by ` group by
distinct 中的字段

多表join的关联列上。

如何选择索引列的顺序?mysql是从左到右的顺序使用的

区分度最高的列表放在联合索引的最左侧
尽量把字段长度小的列放在联合索引的最左侧
使用最频繁的列放到联合索引的左侧

避免建立冗余索引和重复的索引

对于频繁的查询优先考虑使用覆盖索引
覆盖索引:就是包含了所有查询字段的索引(但不是所有字段都加上索引,不是select *)
避免 Innodb表进行索引的二次查找(就是通过查询二级索引获取主键在另行查询)
,覆盖索引可以直接进行关联查找

尽量表面使用外键约束,但在表与表之间进行数据关联建立索引,
外键会影响父表和字表的写操作从而降低性能

数据库字段设计规范

优先选择符合存储需要的最小的数据类型

1.将字符串转化为数字类型存储,例如IP。用Mysql自带的函数存储

INET_ATON(‘255.255.255.255’)=4294967295

INET_NTOA(4294967295)=’255.255.255.255′

2.对于非负型的数据来说,要优先使用无符号整形来存储。

无符号相对于有符号可以多出一倍的存储空间

INT有符号范围、-2147482648~214748367

INT无符号范围、0~4294967295

3.避免使用text、blob数据类型

mysql的内存是不支持text和blob这种大文件数据类型,在进行 排序操作就不能使用数据临时表,只能使用磁盘临时表,会造成二次查询,查询新能会变差。

建议把BLOB或是TEXT列分离到单独的扩展表中

4.建议使用ENUM数据类型

最多能存储65535个ENUM值

修改ENUM值需要使用ALTER语句

ENUM类型的ORDER BY操作效率低,需要额外操作

禁止使用数值作为ENUM的枚举值

5.尽可能把所有列定义为NOT NULL

索引NULL列需要额外的空间来保存,所以要占用更多的空间

进行比较和计算时要对NULL值做特别的处理

6.同财务相关的金额类型数据,不许使用decimal类型

Decimal类型为精准浮点数,在计算时不会丢失精度

占用空间有定义的宽度决定,可用于存储比bigint更大的整数数据

1.非精准浮点:float,double

2.精准浮点:decimal

注意事项

varchar(N)中的N代表的是字符数,而不是字节数

varchar(255)是可以存储255个中文,和其他关系数据不一样

使用UTF8存储汉字varchar(255)=765个字节

过大的长度会消耗更多的内存。

数据库SQL开发规范

1、建议使用预编译语句进行数据库操作

1。优点: 只传参数,比传递SQL语句更高效,相同语句可以一次解析,多次使用,提高处理效率。

2、表面数据类型的隐式转换

一般会出现在where从句上,隐式转换会导致索引失效。

例子:select name,phone from user where id=’111′

3、合理利用表上存在索引,不要盲目的增加索引

避免使用双%号的查询条件。如 a like ‘%123%’ 或前置%,如果是后置%是可以利用上列上面的索引的。

一个SQL只能利用到复合索引中的一列进行范围查询.

解释:加入a,b,c中三列覆盖索引查询,我查询a列的范围,那么bc就用不上

使用left join或 not exists 来优化not in操作,not in 有可能是索引失效。

4、程序链接不同的数据库使用不同的账号,禁止跨库查询

优点:为数据库迁移和分库分表留出余地,降低一会耦合度,避免权限过大而产生的安全风险。

5、禁止使用select * 必须使用 select 字段列表查询

@.会把无用的数据查询出来,消耗更多的CPU和IO以及网路贷款资源。特别对于text这种表来说,text是进行二次读取数据。

@.无法使用覆盖索引

6、禁止使用不含用字段列表的INSERT语句

错误写法:insert into t values(‘a’,’b’,”c);

正确写法:insert into t(c1,c2,c3) values(‘a’,’b’,’c’);

这么做的目的,可减少表结构变更带来的影响

7、避免使用子查询,可以把子查询优化为join操作

子查询的结果集无法使用索引,子查询会产生临时表操作,如果子查询数据量大则严重影响效率,消耗过多的CPU以IO资源。产生慢查询

8、避免使用join关联大多的表

每Join一个表会多占用一部分内存(Join_buffer_size)

会产生临时表操作,影响查询效率,Mysql最多允许关联61个表,建议不超过5个

9、减少通数据库的交互次数

数据库更适合处理批量操作(真对查询)

合并多个相同的操作到一起,可以提高处理效率

10、使用 In 代替 or

in的值不要超过500个 ,in操作可以有效的利用索引

11、禁止使用 order by rand()进行随机排序

会把表中所有符合条件的数据装在到内存中进行排序,会消耗大量的CPU和IO及内存资源

推荐在程序中获取一个随机值,然后从数据库中获取数据的方式

12、WHERE从句中禁止对列进行函数转换和计算

对列进行函数转换或计算会导致无法使用索引

错误语句:where date(createtime)=’20160901′

正确语句:where createtime >=’20160901′ and createtime < 20160902 利用到了索引

13、在明显不会有重复值时使用UNION ALL 而不是UNION

union 会把所有数据放到临时表中会在进行去重操作

union all 不会在对结果集进行去重操作

14、拆分复杂的大SQL为多个小SQL

mysql一个SQL只能使用一个CPU进行计算,sql拆分后可以通过并行来提高处理效率

数据库操作行为操作

1、超过100万的批量写操作,要分批多次进行操作

大批量操作可能会造成严重的主从延迟

binlog日志为row格式会产生大量的日志,避免产生大事务操作

2、对大表数据结构的修改一定要谨慎,会造成严重的锁表操作。尤其是生产环境是不能忍受的。

对于大表使用pt-online-schema-change修改表结构(percona公司出品工具),好处:1.避免大表修改产生的主从延迟。2.避免对表字段进行修改时进行锁表

3、禁止为程序使用的账号赋予super权限

当达到最大连接数限制时,还允许1个有super权限的用户连接,所以super权限只能留给DBA处理问题的账号使用。

4、对于程序连接数据库账号, 遵循权限最小原则

程序使用数据库账号只能在一个DB下使用,不准跨库。

程序使用的账号原则上不准有drop权限

Last modification:February 10, 2020
如果觉得我的文章对你有用,请随意赞赏