~ 规范的数据库设计

数据库设计,就是将数据库中的数据实体及这些数据实体之间的关系进行规划和结构化的过程。


数据库中创建的数据结构的种类及数据实体间建立的复杂关系是决定数据库系统效率的重要因素。如果设计不当,会存在数据操作异常、修改复杂、数据冗余等问题,程序性能会受到影响;通过进行规范的数据库设计,可以消除不必要的数据冗余,获得合理的数据库设计,提高项目的应用性能。


为什么需要规范的数据库设计(先设计再创建数据库)?数据库的设计步骤是什么?!


比如,建造建筑物,如果是盖一间茅屋或简易平房,会有人花钱请人设计房屋图样吗?如果是盖一座大厦呢?同理,在实际的项目开发中,如果系统的存储量较大,设计的表比较多,表和表之间的关系比较复杂,就需要首先考虑规范的数据库设计,然后进行具体的创建库、表的工作。


项目开发需经过需求分析、概要设计、详细设计、代码编写、运行测试和部署上线,以下为各阶段的数据库设计过程:


  • 需求分析:整合 _ 业务和数据处理需求   —>   分析 _ 实体、属性及实体间的关系
  • 概要设计:(实体、属性、联系、映射基数)绘制 E-R 图,并将 E-R 图转换为关系模式
  • 详细(逻辑)设计:绘制数据库模型图,并结合三大范式进行审核

一、需求分析阶段(实体、属性、联系、映射基数)

分析客户的业务和数据处理需求:捕获客户的需求,收集相关的业务数据,了解数据处理过程。


[ 面向需求:实体 - 关系分析 ]  无论数据库的大小和复杂程度如何,在数据库系统分析时,可参考以下步骤:


[1] 收集信息 — 创建数据库前,需充分理解数据库需要完成的任务和功能。

即,需要了解数据库要存储哪些信息(数据),实现哪些功能。如酒店管理系统:

  • 酒店为客人准备充足的客房,后台数据库需要存放每间客房的信息,如客房号、房间类型、价格等。
  • 客人在酒店入住时需办理入住手续,后台数据库需要存放客人的相关信息,如客人姓名、身份证号等。

[2] 标识实体 — 收集需求信息后,须标识数据库要管理的关键对象或实体,如产品或部门等。在系统标识这些实体后,与它们相关的实体就会条理清晰。如酒店管理系统:  // 数据库中的每个不同的实体都拥有一个与其对应的表

  • 客房:单人间、标准间、三人间、豪华间、总统套房
  • 客人:入住酒店的客人的个人信息

实体一般是名词,一个实体只描述一件事,不能重复出现含义相同的实体。


[3] 标识每个实体需要存储的详细信息(属性)— 将数据库中的主要实体标识为表的候选实体后,就要标识每个实体存储的详细信息,也称为该实体的属性,这些属性将组成表中的列。

简单来说,就是需要细分出每个实体包含的子成员信息。如酒店管理系统:

需注意的是:在进行实体属性分解时,含义相同的成员信息不能重复出现,如联系方式、电话。
每个实体对应一张表,实体中的每个子成员对应表中的每一列。


[4] 标识实体之间的关系

关系型数据库有一项非常强大的功能,即它能够关联数据库中各个项目的相关信息。不同类型的信息可以单独存储,但,如果需要,数据库引擎还可以根据需要将数据组合起来。在设计过程中,要标识实体之间的关系,首先需要分析数据库表,确定这些表在逻辑上是如何相关的,然后添加关系列建立起表之间的连接。如酒店管理系统,客房与客人是主从关系,需要在客人实体中标明其入住的客房号。


二、概要设计阶段(面向沟通:E-R 图 & 面向开发:关系模型)

标识出各种实体、属性及实体间的关系,绘制 E-R 图,并与客户沟通,反复进行修改、确认。


在需求分析阶段解决了客户的业务和数据处理需求后,就进入概要设计阶段,和项目团队的其他成员和客户沟通,讨论数据库的设计是否满足客户的业务和数据处理需求。

因此,E-R 图主要便于在项目团队内部、设计人员和客户之间进行沟通,确认需求信息的正确性和完整性。


[ 面向沟通:实体 - 关系模型  ==>  E-R 图 ] 


绘制 E-R 图后,需要反复与客户进行沟通,让客户提出修改意见,以确认系统中的数据处理需求是否正确完整。


[1] 实体:现实世界中具有区分其他事物的特征或属性并与其他事物有联系的事物。

如,酒店管理系统:客房(5015、5017等),客人(张三、李四等)。

[2] 属性(对应表中的列),可以理解为实体的特征。如“客人”的属性有:入住日期、记账日期、交付押金等。


[3] 联系:两个或多个关联实体之间的关联关系


[ E-R 图 ] 像机械行业需要机械制图,建筑行业需要施工图一样,数据库设计也需要图形化的表达方式 E-R(Entity-Relationship)图,也可称为实体-关系图,它包括一些具有特定含义的图形符号,是以图形的方式将数据库的整个逻辑结构表示出来。E-R图的组成包括:

  • 实体,用矩形表示,一般为名词;
  • 属性,用椭圆表示,一般也是名词;
  • 联系,用棱形表示,一般为动词。
  • 映射基数:直线用来联系属性和实体集,也用来联系实体集和联系集;直线可以是有方向的(箭头,可以将其视为指向引用的实体),用来表示联系集的映射基数。

[4] 映射基数:表示通过联系与该实体关联的其他实体的个数。

对应实体集 X 与 Y 之间的二元关系,映射基数必须为下列之一:

  • 一对一:X 中的一个实体最多与 Y 中的一个实体关联,且 Y 中的一个实体最多与 X 中的一个实体关联。如,假设规定每辆汽车同一时刻只能占用一个车位,同一时刻每个车位也只能停一辆汽车。那么,汽车实体与车位实体之间就是一对一的关系。
  • 一对多:X 中的一个实体可以与 Y 中任意数量的实体关联,Y 中的一个实体最多与 X 中的一个实体关联。如,一个客房可以入住多个客人,一个客人只能入住一个客房。所以,客房实体与客人实体是一对多的关系。
  • 多对一:客房实体和客人实体是一对多的关系,反过来说,客人实体和客房实体之间就是多对一的关系。
  • 多对多:X 中的一个实体可以与 Y 中的任意数量的实体关联,反之亦然。如,图书馆的书可以借给多个读者,每个读者也可以借阅多本书。图书实体和读者实体就是典型的多对多关系。

[ 面向开发:关系模型 ] 用二维表的形式表示实体和实体间联系的数据模型称为关系模型。关系数据库模式是对关系数据库结构的描述,或者说是对关系数据库框架的描述。一个关系通常对应一张表。


一般情况下,通常把关系模式表示为如下形式:R(U)   或   R(A,B) 
// 其中,R表示关系名,U表示属性集合,A、B代表U中的属性

So,如何将 E-R 图转换为关系模型呢?


[1] 把每个实体转换为关系实体 R(A,B) 形式,如,酒店管理系统,实体“客人”和“客房”分别用关系模式表示:

客房(客房号、客房描述、客房类型、客房状态、床位数、入住人数、价格)
客人(客人编号、客人姓名、身份证号、入住日期、结账日期、押金、总金额

[2] 建立实体间联系的转换

实体间的关系分为一对一、一对多、多对多三种,当两个实体各自转换为关系模式后,实体间联系的转换为:

  • 一对一:把任意实体的主键放在另一个实体的关系模式中。
  • 一对多:把联系数量为 1 的实体的主键放到联系数量为 N 的实体关系模式中。
  • 多对多:把两个实体的主键和联系的属性放到另一个关系模式中,注意多生成一个关系模式。

酒店管理系统中,客房与客人是一对多的关系,转换后的结果为:

客房(客房号、客房描述、客房类型、客房状态、床位数、入住人数、价格)

客人(客人编号、客人姓名、身份证号、入住日期、结账日期、押金、总金额、客房号

// 说明:含有下划线的属性代表主属性,在表中作为主键;加粗属性为外键。


三、详细(逻辑)设计阶段(数据库模型图)

进行数据库的逻辑设计,将 E-R 图转换为表,并应用三大范式进行审核,使数据库设计规范化。


概要设计阶段解决了客户的需求,并绘制了 E-R 图。详细设计阶段,进行逻辑设计,需把 E-R 图转换为数据库中的多个表,并标识各个表的主键和外键。同时,应用数据库设计的三大范式进行审核,经项目组开会讨论确定后,还需根据项目的技术实现、团队开发能力及项目成本预算,选择具体的数据库(如,MySQL)进行物理实现。


So,如何将 E-R 图转化为数据库模型图?如何审核各表的结构是否规范?


[ 绘制 — 数据库模型图 ]                                                         // 推荐工具:Processon

[1] 将 E-R 图中的各实体转换为对应的表,将各属性转换为各表对应的列。

[2] 标识每个实体的主键列 — 另,要为没有主键的表添加 ID 编号列,该列无实际含义,只用作主键或外键。

// 为了数据编码的兼容性,建议使用英文字段

// 实体-表   属性-表中的列   
// 约束:主键/外键   
// 映射:一对一/一对多/多对多(连接表)

    PK  主键             constraint primary key
    UK  唯一约束         constraint unique key
    DF  约束默认         constrint default for
    CK  检查约束         constraint check()
    FK  主外键关系       constraint foreign references

[3] 在数据库模型图中体现实体间的映射关系:

  • 一对一关系中,一般是一个主键对应一个不可重复的字段,显然只有一个值对应一个值的可能;
  • 一对多关系,是一个表中的主键对应另一个表中的可重复字段,主键的值是不能重复的,而关联字段是可以重复的,就会存在一个值对应多个值的可能,即一对多;
  • 多对多,如学生和课程实体,要表示多对多,除了将多对多的两个实体各自转换为表外,一般还会创建第三个表,称为连接表,它将多对多关系划分为两个一对多关系,然后,将两个表的主键都插入到第三个表中。因此,第三个表记录关系的每个匹配项或实例。

[ 审核 — 规范化与三大范式 ]

从关系型数据库表中除去冗余数据的过程称为规范化。如果使用得当,规范化是用于获得高效的关系型数据库表的逻辑结构的最好、最容易的方法。当规范化数据时,应执行以下操作:

  • 将数据库的结构精简为最简单的形式(简单来说就是,没有重复的列);
  • 从表中删除冗余的列(类似的列合并,如xx月xx日...合并为“日期”);
  • 标识所有依赖于其他数据的数据(即字段之间是直接依赖,而非传递依赖(用户ID-中奖等级-中奖金额))。

数据库设计的三大范式:

  • 第一范式 — 其目标是确保每列的原子性。
  • 第二范式 — 在第一范式的基础上更进一层,其目标是确保表中的每列都和主键相关。
  • 第三范式 — 在第二范式的基础上更进一层,其目标是确保每列都和主键列直接相关,而不是间接相关。

以上步骤完成后,开始进入代码编写阶段,即,开发后台应用程序。