原文地址: https://www.jianshu.com/p/a7823880e6d9
本文为慕课网的《数据库设计那些事》的学习笔记,系统的整理了数据库设计的相关概念和整个流程,并加入了一些内容和链接来补充.
1. 数据库设计简介
建立数据库应用系统的设计看作检大厦的过程。大厦建立之前,要先设计、绘制图纸、按照图纸建设大厦。数据库相当于我们大厦的地基。
1.1 什么是数据库设计?
就是根据业务系统的具体要求,结合我们所选用的数据库管理系统,为这个业务系统构造出最优的数据存储模型,并建立好数据库中的表结构及表与表之间的关联关系的过程。使之能有效的对应用系统中的数据进行存储,并可以高效地对已经存储的数据进行访问。
1.2 常见的数据库管理系统
- 关系型: mysql、oracle、sql server、postgres等
- 非关系型: mongo、memcache、redis
1.3 为什么要进行数据库设计?
数据库系统是应用系统存储数据的关键组成部分,是系统稳定运行的基础,决定着系统是否可以高效地运行。
- 优良的设计:减少数据冗余,避免数据维护异常,节约空间,高效访问。
- 糟糕的设计:存在大量的数据冗余,存在数据插入、更新、删除异常,浪费大量存储空间,访问数据低效。
2. 数据库设计的步骤
- 数据库设计的步骤:
需求分析-〉逻辑设计-〉物理设计-〉维护优化
- 数据库需求的作用点:数据是什么、数据有哪些属性、数据和属性各自的特点有哪些
- 逻辑设计:使用ER图对数据库进行逻辑建模,之后就可以在大多数数据库管理系统中进行表的设计
- 物理设计: 根据数据库自身的特点把逻辑设计转换为物理设计。
- 维护设计:根据新的需求从新进行相关的逻辑设计、建表、索引优化、大表拆分等等
2.1 需求分析
需求分析过程中需要了解的重要内容,直接进行表设计导致设计出来的表不是最优化的,必须首先进行需求分析。
- 了解系统中所要存储的数据有哪些
- 了解数据的存储特点:比如有些有时效性,定期归档和清理。还有些数据增长很快,数据量也很大,但他不是系统的核心数据,分库、分表方式存储。比如日志定期归档和清理
- 了解数据的生命周期
要搞清一些问题:
- 实体(对象)与实体之间的关系 实体与表的对应关系、实体与实体的对应关系 1对1,队多,多对多,
- 实体所包含的属性有什么?
- 哪些属性或属性的组合可以唯一标识一个实体,
示例:
购物车模块:
用于保存用户购物是选对的商品
包括属性:用户名、商品编号、商品名称、商品价格、商品描述、商品分类,加入时间,商品数量
可选唯一标识:(用户名、商品编号、加入时间)、(购物车编号)
存储特点:不用永久存储(设置归档、清理规则)
供应商模块:
用于保存所销售商品的供应商信息
包括属性:供应商上编号、供应商名称、联系人、电话、营业执照号、地址、法人。。。
可选唯一标识:(供应商编号),(营业执照号)
存储特点:永久存储
2.2 逻辑设计
- 将需求转化为数据库的逻辑模型
- 通过ER图的形式对逻辑模型进行展示
- 同所选用的具体的数据库管理系统无关
2.3 物理设计
流程:
- 选择合适的数据库管理系统(DBMS: oracle,mysql等).
- 定义数据库、表及字段的命名规范.
- 根据所选的DBMS系统选择合适的字段类型.
- 反规范设计.
2.3.1 mysql常见存储引擎(以mysql为例)
2.3.2 表以及字段的命名规范
- 可读性原则: 使用大写和小写来格式化的库对象名字以获得良好的可读性.例如:使用CustAddress 而不是custaddress
- 表意性原则: 名称体现意义
- 长名原则:尽可能少使用或者不使用缩写
2.3.3 字段类型的选择原则
- 考虑存储开销
- 考虑查询性能
2.3.4 数据库设计其他注意事项
- a. 如何选择主键:
- 区分业务主键和数据库主键
- 业务主键用于标识业务数据,进行表与表之间的关联
- 数据库主键为了优化数据库存储(Innodb会生成6个字节的隐含主键)
- 根据数据库的类型,考虑主键是否要顺序增长
- 有些数据库是按主键的顺序逻辑存储的
- 主键的字段类型所占空间要尽可能的小
- 对于使用聚集索引方式存储的表,每个索引后都会附加主键信息
- 区分业务主键和数据库主键
- b. 避免使用外键约束, 原因:
- 降低数据导入的效率
- 增加维护成本
- 虽然不建议使用外键约束,但是相关关联的列上一定要建立索引
- c. 避免使用触发器, 原因:
- 降低数据导入的效率
- 可能会出现意想不到的数据异常
- 使业务逻辑变的复杂
- d. 关于预留字段, 原因:
- 无法准确的知道预留字段的类型
- 无法准确的知道预留字段中所存储的内容
- 后期维护预留字段所要的成本,同增加一个字段所需要的成本是相同的
- 严禁使用预留字段
2.3.5 反范式化表设计
反范式化:允许存在少量的数据冗余,适当对第三范式进行违反,
目的:使用空间来换取时间,提高性能和读写效率。
为什么反范式化:
- 减少表的关联数量
- 增加数据的读取效率
- 反范式化一定要适度
示例:
2.4 维护优化
维护和优化的工作:
- 维护数据字典
- 维护索引
- 维护表结构
- 在适当的时候对表进行水平拆分和垂直拆分
2.4.1 如何维护数据字典
- 使用第三方工具对数据字典进行维护
- 利用数据库本身的备注字段来维护数据字典
2.4.2 如何维护索引
如何选择合适的列建立索引:
- 出现在WHERE从句,GROUP BY从句,ORDER BY从句中的列
- 可选性高的列要放到索引的前面
- 索引中不要包括太长的数据库类型
注意事项: - 索引并不是越多越好,过多的索引不但会降低写效率,而且会降低读的效率
- 定期维护索引碎片
- 在SQL 语句中不要使用强制索引关键字
2.4.3 维护表结构
注意事项
- 使用在线变更表结构的工具
- 同时对数据库字典进行维护
- 控制表的宽度和大小
数据库中适合的操作 - 批量操作,逐条操作都有,推荐使用批量操作
- 禁止使用
Select *
这样的查询 - 控制使用用户自定义函数
- 不要使用数据库中的全文索引
2.4.4 对表进行拆分
表的垂直拆分: 为了控制表的宽度可以进行表的垂直拆分
1.经常一起查询的列放到在一起
2.text,blob等大字段拆分到附加表中
表的水平拆分: 为了控制表的大小可以进行表的水平拆分
- 通过主键hash key的操作(按模取值)
- 时区段域拆分
- 表业务类型拆分
2.4.5 其他
数据库分区:
- range分区
- list分区
- hash分区
- key分区
- 子分区