关系数据库管理系统(RDMS)

关系数据库设计(RDD)将信息和数据建模为一组具有行和列的表。关系/表的每一行代表一条记录,每一列代表数据的属性。结构化查询语言(SQL)用于处理关系数据库。关系数据库的设计由四个阶段组成,其中将数据建模为一组相关表。阶段是-

  • 定义关系/属性

  • 定义主键

  • 定义关系

  • 正常化

关系数据库在组织数据和执行事务方面的方法与其他数据库不同。在RDD中,数据被组织成表格,并且所有类型的数据访问都通过受控事务进行。关系数据库设计满足数据库设计所需的ACID(原子性,一致性,完整性和持久性)属性。关系数据库设计要求在应用程序中使用数据库服务器来处理数据管理问题。

 

关系数据库设计过程

数据库设计比科学更是一门艺术,因为您必须做出许多决定。通常对数据库进行定制以适合特定的应用程序。没有两个定制的应用程序是相同的,因此,没有两个数据库是相同的。在制定这些设计决策时会提供一些指导原则(通常是根据不做什么而不是做什么),但最终选择权取决于设计者。

步骤1-定义数据库的目的(需求分析)

  • 收集需求并定义数据库的目标。

  • 草拟样本输入表单,查询和报告通常会有所帮助。

步骤2-收集数据,组织表并指定主键

  • 确定数据库的用途后,收集需要存储在数据库中的数据。将数据划分为基于主题的表。

  • 选择一列(或几列)作为所谓的主键,它唯一地标识每一行。

第3步-在表之间创建关系

由独立且不相关的表组成的数据库几乎没有用(您可以考虑使用电子表格)。关系数据库的功能在于可以在表之间定义的关系。设计关系数据库中最关键的方面是识别表之间的关系。关系的类型包括:

  • 一对多

  • 多对多

  • 一对一

一对多

在“班级名册”数据库中,一位老师可以教零个或更多班,而一个班级却由一位(只有一位)老师教。在“公司”数据库中,一个经理管理零个或多个员工,而一个员工则由一个(只有一个)经理管理。在“产品销售”数据库中,客户可以下很多订单;而一个特定客户下的订单。这种关系称为一对多。

一对多关系不能在单个表中表示。例如,在“班级名册”数据库中,我们可以从一个名为“教师”的表开始,该表存储有关教师的信息(例如姓名,办公室,电话和电子邮件)。为了存储每位老师教的课,我们可以创建列class1,class2,class3,但是立即面临创建多少列的问题。另一方面,如果我们从一个名为Classes的表开始,该表存储有关一个班级的信息,我们可以创建其他列来存储有关(一位)老师的信息(例如姓名,办公室,电话和电子邮件)。但是,由于教师可能会教很多课程,因此其数据将在表“课程”的许多行中重复。

为了支持一对多关系,我们需要设计两个表:例如,一个表Classs,用于存储有关以classID作为主键的类的信息;还有一个教师表,用于存储有关以教师ID为主要键的教师的信息。然后,我们可以通过将表Teacher(即TeacherID)(“ one” -end或父表)的主键存储在表类(“ many” -end或子表),如下图所示。

  子表Classes中的列TeacherID被称为外键。子表的外键是父表的主键,用于引用父表。

多对多

在“产品销售”数据库中,客户的订单可能包含一个或多个产品;产品可以出现在许多订单中。在“书店”数据库中,一本书是由一个或多个作者撰写的;而作者可能写零本书或更多本书。这种关系被称为多对多。

让我们用“产品销售”数据库进行说明。我们从两个表开始:产品和订单。表格产品包含有关产品的信息(例如名称,说明和quantageInStock),其中产品ID为主键。表订单包含客户的订单(customerID,dateOrdered,dateRequired和状态)。同样,我们无法将订购的项目存储在Orders表中,因为我们不知道要为项目保留多少列。我们也无法将订单信息存储在“产品”表中。

为了支持多对多关系,我们需要创建第三个表(称为联结表),例如OrderDetails(或OrderLines),其中每行代表一个特定订单的项目。对于OrderDetails表,主键由两列组成:orderID和productID,它们唯一地标识每一行。OrderDetails表中的orderID和productID列用于引用Orders和Products表,因此,它们也是OrderDetails表中的外键。

 

实际上,通过引入联结表,多对多关系被实现为两个一对多关系。

 订单在OrderDetails中有很多项目。OrderDetails项目属于一个特定订单。

 产品可能会出现在许多OrderDetails中。每个OrderDetails项目都指定一个产品。

一对一

在“产品销售”数据库中,产品可能具有可选的补充信息,例如图像,更多描述和评论。将它们保留在Products表中会导致许多空白(在那些没有这些可选数据的记录中)。此外,这些大数据可能会降低数据库的性能。

相反,我们可以创建另一个表(例如ProductDetails,ProductLines或ProductExtras)来存储可选数据。仅将为带有可选数据的那些产品创建一条记录。两个表Products和ProductDetails表现出一对一的关系。也就是说,对于父表中的每一行,子表中最多有一行(可能为零)。同一列productID应该用作两个表的主键。

某些数据库限制了可在表内创建的列数。您可以使用一对一关系将数据分成两个表。一对一关系对于将某些敏感数据存储在安全表中而将非敏感数据存储在主表中也很有用。

列数据类型

您需要为每列选择适当的数据类型。通常,数据类型包括整数,浮点数,字符串(或文本),日期/时间,二进制,集合(例如枚举和集合)。

步骤4-优化和规范化设计

 例如,

  •  添加更多列,

  • 使用一对一关系为可选数据创建一个新表,

  • 将一张大桌子分成两个小桌子,

  • 其他方法。

正常化

应用所谓的规范化规则来检查数据库在结构上是否正确和最佳。

第一范式(1NF):如果每个单元格包含一个值而不是值列表,则表为1NF。此属性称为原子。1NF还禁止重复的列组,例如item1,item2,itemN。相反,您应该使用一对多关系创建另一个表。

第二范式(2NF)-如果表为1NF,并且每个非键列都完全依赖于主键,则表为2NF。此外,如果主键由几列组成,则每个非键列应取决于整个集合而不是其一部分。

例如,OrderDetails表的主键包含orderID和productID。如果unitPrice仅取决于productID,则不应将其保留在OrderDetails表中(而是在Products表中)。另一方面,如果单价取决于产品以及特定订单,则应将其保留在OrderDetails表中。

第三范式(3NF)-如果表为2NF并且非键列彼此独立,则表为3NF。换句话说,非键列依赖于主键,仅依赖于主键而没有别的。例如,假设我们有一个Products表,其中包含productID(主键),name和unitPrice列。如果columnRateRate列还取决于不属于主键的unitPrice,则该列不属于Products表。

高范式: 3NF有其不足之处,这导致了高范式 ,例如Boyce / Codd范式,第四范式(4NF)和第五范式(5NF),这超出了本教程的范围。

 有时,出于性能原因,您可能决定破坏某些规范化规则(例如,在Orders表中创建一个名为totalPrice的列,该列可以从orderDetails记录派生);或因为最终用户要求。确保您完全了解它,开发用于处理它的编程逻辑,并正确记录该决定。

诚信规则

您还应该应用完整性规则来检查设计的完整性-

   1.实体完整性规则-主键不能包含NULL。否则,它不能唯一地标识该行。对于由几列组成的组合键,所有列均不能包含NULL。大多数RDBMS都会检查并执行此规则。

   2.Referential Integrity Rule-每个外键值必须与被引用表(或父表)中的主键值匹配。

仅当父表中存在值时,才可以在子表中插入带有外键的行。

如果父表中键的值发生了更改(例如,更新或删除了该行),则必须对子表中具有此外键的所有行进行相应的处理。您可以(a)禁止更改;(b)相应地在子表中级联更改(或删除记录);(c)将子表中的键值设置为NULL。

可以将大多数RDBMS设置为以指定的方式执行检查并确保引用完整性。

    3.业务逻辑完整性-除了以上两个通用的完整性规则外,还可能存在与业务逻辑有关的完整性(验证),例如,邮政编码应在一定范围内为5位数字,交货日期和时间应属于业务范围小时; 订购的数量应等于或小于库存的数量,等等。这些可以通过无效规则(针对特定列)或编程逻辑来执行。

列索引

您可以在选定的列上创建索引,以方便数据搜索和检索。索引是一种结构化文件,可以加快SELECT的数据访问速度,但可能会降低INSERT,UPDATE和DELETE的速度。如果没有索引结构,则要使用匹配条件(例如SELECT * FROM Customer WHERE name ='Tan Ah Teck')处理SELECT查询,数据库引擎需要比较表中的每个记录。专用索引(例如,BTREE结构中的索引)可以达到记录,而无需比较每个记录。但是,无论何时更改记录,都需要重建索引,这会导致与使用索引相关的开销。

可以在单个列,一组列(称为串联索引)或列的一部分(例如VARCHAR(100)的前10个字符)(称为部分索引)上定义索引。您可以在一个表中建立多个索引。例如,如果您经常使用customerName或号码搜索客户,则可以通过在customerName列和phoneNumber上建立索引来加快搜索速度。大多数RDBMS会自动在主键上建立索引。