目录
基础规范
:::info
表必须有主键,建议使用整型作为主键
禁止使用外键,表之间的关联性和完整性通过应用层来控制
表在设计之初,应该考虑到大致的数据级,若表记录小于1000W,尽量使用单表,不建议分表。
建议将大字段,访问频率低,或者不需要作为筛选条件的字段拆分到拓展表中,(做好表垂直拆分)
控制单实例表的总数,单个表分表数控制在1024以内。
:::
列设计规范
:::info
正确区分tinyint、int、bigint的范围
使用varchar(20)存储手机号,不要使用整数
使用int存储ipv4 不要使用char(15)
涉及金额使用decimal/varchar,并制定精度
不要设计为null的字段,而是用空字符,因为null需要更多的空间,并且使得索引和统计变得更复杂。
:::
索引规范
:::info
唯一索引使用uniq_[字段名]来命名
非唯一索引使用idx_[字段名]来命名
不建议在频繁更新的字段上建立索引
非必要不要进行JOIN,如果要进行join查询,被join的字段必须类型相同,并建立索引。
单张表的索引数量建议控制在5个以内,索引过多,不仅会导致插入更新性能下降,还可能导致MYSQL的索引出错和性能下降
组合索引字段数量不建议超过5个,理解组合索引的最左匹配原则,避免重复建设索引。比如你建立了
(x,y,z) 相当于你建立了(x),(x,y),(x,y,z)
:::
SQL规范
:::info
禁止使用selet *,只获取必要字段,select *会增加CPU/IO/内存、带宽的消耗。
insert 必须指定字段,禁止使用insert into Table values().指定字段插入,在表结果变更时,能保证对应应用程序无影响。
隐式类型转换会使索引失效,导致全表扫描。(比如:手机号码搜索时未转换成字符串)
禁止在where后面查询列使用内置函数或者表达式,导致不能命中索引,导致全表扫描
禁止负向查询(!=,not like ,no in等)以及%开头的模糊查询,造成不能命中索引,导致全表扫描
避免直接返回大结果集造成内存溢出,可采用分段和游标方式。
返回结果集时尽量使用limit分页显示。
尽量在order by/group by的列上创建索引。
大表扫描尽量放在镜像库上去做
禁止大表join查询和子查询
尽量避免数据库内置函数作为查询条件
应用程序尽量捕获SQL异常
:::
表的垂直拆分
:::info
垂直拆分:业务模块拆分、商品库,用户库,订单库
水平拆分:对表进行水平拆分(也就是我们说的:分表)
表进行垂直拆分:表的字段过多,字段使用的频率不一。(可以拆分两个表建立1:1关系)
将一个属性过多的表,一行数据较大的表,将不同的属性分割到不同的数据库表中。以降低单库表的大小。
特点:
每个表的结构不一致
每个表的数量都是全量
表和表之间一定会有一列会进行关联,一般都是主键
原则:
将长度较短,访问频率较高的字段放在一个表中,主表
将长度较长、访问频率比较低的字段放一个表中
将经常访问字段放一个表中。
所有表的并集是全量数据。
:::
如何平滑添加字段
:::info
场景:在开发时,有时需要给表加字段,在大数据量且分表的情况下,怎么样平滑添加。
- 直接alter table add column,数据量大时不建议,(会产生写锁)
:::
# 增加用户表字段:用户扩展订单号
alter table ksd_user add column api_pay_no varchar(32) not null comment '用户扩展订单号';
# 增加用户表字段:用户扩展订单号,并设置为唯一约束
alter table ksd_user add column api_pay_no varchar(32) not null unique comment '用户扩展订单号';
:::info
- 提前预留字段(不优雅:造成空间浪费,预留多少很难控制,拓展性差)
- 新增一张表,(增加字段),迁移原表数据,在重新命名新表作为原表。
- 放入扩展表(无法使用索引)
- 提前设计,使用key/value方法存储,新增字段时 ,直接加一个key就好了,如:redis(优雅)
:::
原创文章,作者:wdmbts,如若转载,请注明出处:https://blog.ytso.com/tech/database/275097.html