业务设计——逻辑设计及物理设计
逻辑设计
针对数据库的逻辑设计主要是指范式设计和反范式设计,首先来看一下我们的范式设计
范式设计
1. 第一范式
- 数据库表中的所有字段都只具有单一属性
- 单一属性的列是由基本数据类型所构成的
- 设计出来的表都是简单的二维表
比如在用户表User中,我们可以有姓名、性别、年龄…,这些都是单独的列,不能够把性别和年龄组合一起当成一个列。如下:
姓名 | 性别-年龄 | … |
---|---|---|
张三 | 男-18 | … |
2. 第二范式
- 要求表中只具有一个业务主键,也就是说符合第二范式的表不能存在非主键列只对部分主键的依赖关系
比如我们订单表中,我们一张订单中可能有多个商品,我们将订单id和商品id放在一起,如下:
订单ID | … | 商品ID |
---|---|---|
20191207 | … | 1A0001 |
20191207 | … | 1A0002 |
因为订单id和商品id是没有直接关联的,这里我们应该将其分开,然后再新建一张中间表,主要存储订单和商品的对应关系表。
3. 第三范式
- 指每一个非非主属性既不部分依赖于也不传递依赖于业务主键,也就是在第二范式的基础上删除了非主键对主键的传递依赖
比如我们在订单中,一个订单可能有购买人即客户,但是我们保存了客户的id,不能又保存客户的其他信息,如姓名、手机号等,如下:
订单ID | … | 客户ID | 客户姓名 |
---|---|---|---|
0191207 | … | 001 | 张三 |
因为一个订单肯定有一个客户,她和客户ID和客户姓名都是有对应关系的,但是我们的客户ID和客户姓名肯定也是对应的,这是我们想要改变一个订单的客户,不仅需要改变其ID,还需改变其姓名,这里我们就应该删除客户姓名列。
反范式设计
但是我们在日常工作中,肯定也见到了很多很多和我们上述范式也不相符的地方,因为我们如果严格意义上完全按照我们的范式设计数据库的表结构,我们会发现在我们想要查询一些数据时,我们有时往往需要关联N多张表,比如很多的中间关系对于的表等等,大量的表关联就会非常非常影响查询的性能。
所以就又有了反范式设计,什么叫反范式化设计,如下:
- 反范式化是针对范式化而言得,在前面介绍了数据库设计的范式
- 所谓得反范式化就是为了性能和读取效率得考虑而适当得对数据库设计范式得要求进行违反
- 允许存在少量得冗余,换句话来说反范式化就是使用空间来换取时间
比如我们有时就可以不用中间表来存储其对应关系,我们可以直接将一张表的id直接作为另一张表的一列,我们也可以在表中冗余一部分的常用数据,来避免频繁的表关联等情况。
范式化设计优缺点:
优点:
- 可以尽量得减少数据冗余
- 范式化的更新操作比反范式化更快
- 范式化的表通常比反范式化的表更小
缺点:
- 对于查询需要对多个表进行关联
- 更难进行索引优化
反范式化设计优缺点
优点:
- 可以减少表的关联
*可以更好的进行索引优化
缺点:
- 存在数据冗余及数据维护异常
- 对数据的修改需要更多的成本
物理设计
定义数据库、表及字段的命名规范
- 数据库、表、字段的命名要遵守可读性原则,使用大小写来格式化的库对象名字以获得良好的可读性
例如:使用customerAddress或者customer_address而不是customeraddress来提高可读性。
- 数据库、表、字段的命名要遵守表意性原则,对象的名字应该能够描述它所表示的对象
例如:对于表,表的名称应该能够体现表中存储的数据内容;对于存储过程,存储过程应该能够体现存储过程的功能。
- 数据库、表、字段的命名要遵守长名原则,尽可能少使用或者不使用缩写
选择合适的存储引擎
在 MySQL逻辑架构及存储引擎 中我们介绍了好几种存储引擎,其实最常用的就是MyISAM和InnoDB,一般我们也只是在这两种之间选择,在选择时,我们应该清楚业务的需求以及这两种引擎的优缺点。
为表中的字段选择合适的数据类型
当一个列可以选择多种数据类型时,我们可以按照以下的几点进行考虑:
- 优先考虑数字类型
- 其次是日期、时间类型
- 最后是字符类型
- 对于相同级别的数据类型,应该优先选择占用空间小的数据类型