美文网首页
Mysql的设计原则整理记录

Mysql的设计原则整理记录

作者: 54番茄 | 来源:发表于2021-08-06 17:35 被阅读0次

    在项目技术选型时,原则上是选择成熟的平台和技术,同时最好是自己最熟悉的,能做到极致的,用好不用坏,用熟不用生,不然发现问题,你会无从查骑,当然如果你已经有了技术储备,尝鲜未尝不可。

    基础规范

    • 单表数据量建议控制在 3000 万以内,所有表都需要添加注释,表在设计之初,应该考虑到大致的数据级,若表记录小于1000W,尽量使用单表,不建议分表。
    • 主键推荐使用自增列,主键不应该被修改,字符串不应该做主键,如果不指定主键,INNODB 会使用唯一且非空值索引代替,建议使用整型作为主键
    • 禁止使用外键,表之间的关联性和完整性通过应用层逻辑来控制
    • 不能在数据库中存储图片、文件等大数据
    • 非必要不建议保存大字段数据,如需要建议将大字段,访问频率低,或者不需要作为筛选条件的字段拆分到拓展表中,分离冷热数据(做好表垂直拆分)
    • 经常需要计算和排序等消耗CPU的字段,应该尽量选择更为迅速的字段,如用TIMESTAMP(4个字节,最小值1970-01-0100:00:00)代替Datetime(8个字节,最小值1001-01-01 00:00:00),通过整型替代浮点型和字符型;变长字段使用varchar,不要使用char
    • 存储引擎选择:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎
    • 同财务金额相关的数据必须使用 decimal 类型

    索引规范

    • 唯一索引使用uniq_[字段名]来命名
    • 非唯一索引使用idx_[字段名]来命名
    • 不建议在频繁更新的字段上建立索引
    • 非必要不要进行JOIN,如果要进行JOIN查询,被JOIN的字段必须类型相同,并建立索引,不要超过三个表JOIN
    • 单张表的索引数量建议控制在5个以内,索引过多,不仅会导致插入更新性能下降,还可能导致MYSQL的索引出错和性能下降,不要在低基数列上建立索引,例如‘性别’,浪费
    • 组合索引字段数量不建议超过5个,理解组合索引的最左匹配原则,避免重复建设索引(避免冗余)。比如你建立了(x,y,z)相当于你建立了(x),(x,y),(x,y,z)

    SQL规范

    • 尽可能把所有列设定默认值,空字符串或0,不要设定NULL,索引 NULL 列需要额外的空间来保存,所以要占用更多的空间。
    • 尽量不要使用select *全列查 ,最好是只获取必要字段,select *会增加cpu/i0/内存、带宽的消耗,可减少表结构变更带来的影响。
      insert必须指定字段,禁止使用insert into Table values()插入数据,在表结果变更时,能保证对应应用程序无影响。
    • 隐私类型转换会使索引失效,导致全表扫描。(比如:手机号码搜索时未转换成字符串)
    • 禁止在where后面查询列使用内置函数或者表达式,导致不能命中索引,导致全表扫描.
    不推荐:
    where date(create_time)='20210000'
    推荐:
    where create_time >= '20210000' and create_time < '20212000'
    
    • 禁止负向查询(!=,not like ,no in等)以及%开头的模糊查询,造成不能命中索引,导致全表扫描
    • 避免直接返回大结果集造成内存溢出,可采用分段和游标方式。返回结果集时尽量使用limit分页显示。
    • 尽量在order by/group by的列上创建索引。
    • 对应同一列进行 or 判断时,使用 in 代替orIn 的值不要超过 500 个,in 操作可以更有效的利用索引,or 大多数情况下很少能利用到索引。

    关系型数据库设计:三大范式

    第一范式: 要求数据库表的每一列都是不可分割的原子数据项。
    第二范式: 在第一范式的基础上,需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关
    第三范式: 在第二范式的基础上,需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
    打破范式标准:
    建议建表的时候,就把这些列放在一个表里,比如一开始有student(id, name),class(id, description),student_class(student_id, class_id)三张表,这样是符合数据库范式的(第一范式,第二范式,第三范式,BC范式等),没有任何冗余,但是马上就不符合“编程规范“了,那我们可以用一张大表代替它,student_class_full(student_id, class_id, name, description),这样name和description可能要被存储多份,但是由于不需要join了,查询的性能就可以提高很多了。
    任何的规范都是在特定情况下的某种妥协,脱离了这个环境,就不一定成立了。
    需要说明的是,这种脱离范式的设计,是互联网业务在设计高并发表时惯用的做法。

    表的拆分

    • 垂直拆分
      将一个属性过多的表,一行数据较大的表,将不同的属性分割到不同的数据库表中。以降低单库表的大小,把有关联但是独立的数据拆分为两个表,如用户表和部门表。
      特点:
      每个表的结构不一致
      每个表的数量都是全量
      表和表之间一定会有一列会进行关联,一般都是主键

    原则:
    将长度较短,访问频率较高的字段放在一个表中,主表
    将长度较长、访问频率比较低的字段放一个表中
    将经常访问字段放一个表中。
    所有表的并集是全量数据。

    • 水平拆分
      单表数据过大,IO瓶颈限制查询速度,对表进行水平拆分(也就是我们说的:分表),比如根据时间维度分表。
    大数据表添加字段需要注意

    在开发时,有时需要给表加字段,在大数据量且分表的情况下,怎么样稳定的添加。
    1:直接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 '用户扩展订单号'
    

    2:提前预留字段(不优雅:造成空间浪费,预留多少很难控制,拓展性差)
    3:新增一张表,(增加字段),迁移原表数据,在重新命名新表作为原表。
    4:放入extinfo(无法使用索引)
    5: 提前设计,使用key/value方法存储,新增字段时 ,直接加一个key就好了(优雅)

    相关文章

      网友评论

          本文标题:Mysql的设计原则整理记录

          本文链接:https://www.haomeiwen.com/subject/pjubvltx.html