数据库设计

2020/06/11 数据库

概述

是什么

所谓的数据库设计就是根据需求文档的描述将需求转成数据库的存储结构的过程.

在数据库设计的流程上,我们通常根据需求,画出数据的ER图.然后在通过ER图生成数据库的建库脚本. (Entity Relational)

ER图,所谓的ER图就是数据库关系图

为什么我们使用ER图来实现数据库设计的设计呢?

1.可见即可得.使用ER图可以通过图形的方式展示表与表直接的关系

2.可以根据设置的数据库,方便生成不同的数据库的SQL建库脚本

3.可以快速的生成数据库文档

小结:所谓的数据库设计,就是通过ER图,根据需求给数据库建表表结构!!!

数据库E-R图一般包含的元素有:实体(方框表示),联系(菱形表示),属性(椭圆表示),联系(直线表示)相关表示符号见下图:

draw.io怎么创建实体关系图

为什么

软件开发都是分别从页面设计和数据库设计开始的.

创建项目的数据库是项目开发必须的阶段.

基础理论

步骤

数据库设计的步骤是根据需求的描述:

第一步:标识表

第二步:标识表的字段

第三步:标识表与表之间的关系

标识表注意事项

所谓的标识表,就是根据需求将表创建!!

我们在标识表的时候,可以将表分为实体表和业务表.

所谓的实体表:就是记录需求中描述为一个对象(名词)的表.如:用户,商品,订单,管理员,角色等

所谓的业务表:就是记录在需求中描述为一个业务行为(动词)的表:收藏,关注,等 (大部分是中间表)

虽然没有强制的规定先标识实体表还是业务表,但我们通常在标识表时会先标识实体表,再标识业务表.

因为业务表一般是用于标识实体表与另一个实体的多对多的关系的.

标识字段注意事项

标识字段,在数据库设计中,尽量符合数据库设计的三大范式原则.

–三大范式,就是用于数据库设计,标识字段的时候使用的!!!。

数据库表设计三大范式最终解决的是数据冗余问题

标识表与表之间的关系

  1. 有哪些表与表之间关系,一对多,多对一,一对一,多对多

  2. 表与表之间的关系是由需求决定,讨论表之间的关系前,必须要先确定需求

  3. 关系数据库是不能直接支持多对多的业务关系的,如果出现多对多必须要拆分一个中间表,原因是数据库里面的字段不能存储一个集合数据。

三大范式

为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。

在实际开发中最为常见的设计范式有三个

第一范式(确保每列保持原子性)

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式,如下表所示。

上表所示的用户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。

第二范式(确保表中的每列都和主键相关)

非主键列必须依赖主键列存在

第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示。

订单信息表

这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。

而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示。

这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可。

第三范式(确保每列都和主键列直接相关,而不是间接相关-在2NF基础上消除传递依赖)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。

这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输入客户信息的内容,减小了数据冗余。

三大范式只是一般设计数据库的基本理念,可以建立冗余较小、结构合理的数据库。如果有特殊情况,当然要特殊对待,数据库设计最重要的是看需求跟性能,需求>性能>表结构(范式)。所以不能一味的去追求范式建立数据库。

实际开发不符合三范式的场景

示例1-性能的要求出现的冗余数据

我们很多系统都要记录日志.而日志里面,必须要包括用户的信息.如果严格按照三大方式.日志的用户信息必须是从用户表中获得,日志每天都会出现巨量的数据。如果关联用户表查询,整理日志时会导致用户表的访问大大被拖慢。

所以,我们会将用户的信息直接写在日志表里面。在日志表中写用户的的信息,明显违反了第二范式,基于查询的性能的需要,一般日志表的用户信息是冗余。

示例2-业务逻辑的要求出现的冗余数据

我们在订单中有一个商品的价格、商品名字。而这个商品的价格直接就是订单的字段.并不是商品表里面商品的价格.明显违反了第三范式.

但业务上,由于订单的商品的价格不能随着着商家修改了商品价格而修改.所以像这种需求下,必须要给订单表一个冗余的商品价格字段。

参考

可扩展的用户表设计
设计一个可扩展的用户登录系统 (1)
设计一个可扩展的用户登录系统 (2)
设计一个可扩展的用户登录系统 (3)

Search

    Table of Contents