第一范式 (1NF)

3 Dec 2024 | 6 分钟阅读
  • 如果一个关系包含原子值,则它将是第一范式(1NF)。
  • 它规定表中的属性不能包含多个值。它必须只包含单值属性。
  • 第一范式不允许多值属性、复合属性及其组合。

示例: 由于多值属性 EMP_PHONE,关系 EMPLOYEE 不符合 1NF。

EMPLOYEE 表

EMP_IDEMP_NAMEEMP_PHONEEMP_STATE
14John7272826385,
9064738238
UP
20Harry8574783832比哈尔邦
12山姆7390372389,
8589830302
旁遮普邦

上面的 EMPLOYEE 表是一个未规范化的关系,因为它包含与 EMP_PHONE 属性对应的多个值,即这些值是非原子的。因此,具有多值条目的关系称为未规范化关系。

为了解决这个问题,我们必须消除 EMP_PHONE 属性的非原子值。

EMPLOYEE 表分解为 1NF 的示例如下所示

EMP_IDEMP_NAMEEMP_PHONEEMP_STATE
14John7272826385UP
14John9064738238UP
20Harry8574783832比哈尔邦
12山姆7390372389旁遮普邦
12山姆8589830302旁遮普邦

有 3 种方法可以实现第一范式。

方法 1

为了消除列的重复值,EMPLOYEE 表通过重复表中的每个条目 (EMP_ID, EMP_NAME) 对,转换为平面关系 EMPLOYEE_1 表。现在新关系不包含任何非原子值,因此该表被认为是规范化的,并且处于第一范式。

方法 2

另一种方法是删除违反 1NF 的属性,并将其与主键一起放入单独的关系中。因此,未规范化的关系 EMPLOYEE 表被分解为两个子关系 EMP_DETAILS 和 EMP_PERFORMANCE

EMP_DETAILS

EMP_IDEMP_NAME
14John
20Harry
12山姆

EMP_PERFORMANCE

EMP_IDEMP_PHONEEMP_STATE
147272826385UP
149064738238UP
208574783832比哈尔邦
127390372389旁遮普邦
128589830302旁遮普邦

分解关系的主要思想是将不同类型的信息保存在各自的关系中,因为第一范式不允许具有复合性质的多值属性。在 EMP_DETAILS 关系中,属性 (EMP_ID) 作为主键,在 EMP_PERFORMANCE 关系中,属性 (EMP_ID, EMP_PHONE) 作为主键。现在它满足了关系处于 1NF 的两个条件。

关系根据以下规则分解:

  • 一个关系由原始关系(即 EMPLOYEE)的主键(EMP_ID)和原始关系(即 EMP_NAME)的非重复属性组成。
  • 另一个关系由原始关系主键的副本和原始关系的所有重复属性组成。

方法 3

将未规范化关系规范化为 1NF 的第三种方法将通过以下示例进行解释,其中某个公司的员工技能是固定的。假设一名员工最多可以拥有五种技能。

EMP_SKILL 关系

EMP_ID技能
14DBMS, C, C++
20JAVA, C
12DBMS, HTML, VB, MS OFFICE

这里 EMP_SKILL 关系 不符合 1NF,因为技能属性包含一组值。因此,为了解决这个问题,我们定义了多个技能列,如下所示。

上述关系在以下示例中被分解为 1NF。

EMP_ID技能_1技能_2技能_3技能_4技能_5
14DBMSCC++--
20JAVAC---
12DBMSHTMLVBMS OFFICE-

上述表示处于 1NF,但这种技术不被推荐,因为它可能导致以下问题:

  • 查询关系会很困难。例如,回答“哪个员工共享一项技能?”、“哪些员工拥有技能 C?”等查询会很困难。
  • 员工技能限制为 5 项。如果出现拥有更多技能的员工,将无法记录。

总而言之,所有这三种方法都是正确的,因为它们将任何未规范化的表转换为第一范式表。然而,将表分解为关系的方法效率更高,因为它可以最大限度地减少数据重复。因此,要使关系处于第一范式,每组重复的组都应该出现在自己的表中,并且每个关系都应该有一个主键。

第一范式中的异常

第一范式关注的是关系表示的结构,而第二范式关注的是消除这些关系中的冗余。

各种异常可以分为:

  • 插入异常
  • 删除异常
  • 更新异常

这些异常的名称来源于它们对关系执行的关系操作。

让我们以 ORDER_BOOK 关系为例:

订单号书名数量价格
4253C15175
4253数据库20225
4154IT30200
4256C50175
4186数据库15225

插入异常: 假设我们想在 ORDER_BOOK 关系中插入一本新书的信息。但是我们无法插入此信息,除非为它下订单,因为在此关系中,主键由两个属性 Order_No 和 B_Name 组成,它们被称为复合键。

因此,Order_No 和 B_Name 都不能包含空值,因为它违反了实体完整性原则。所以我们无法插入尚未下订单的新书信息,因为在这种情况下,属性 Order_No 将包含空值,这违反了实体完整性规则,即主键不能为空值。如下图所示:

订单号书名数量价格
4253C15175
4253数据库20225
4154IT30200
4256C50175
4186数据库15225
NULL操作系统30300

表现出这种不良性质的关系被称为存在插入异常。

删除异常: 假设订单号为 4154 的订单因某些原因被取消。因此,我们必须从 ORDER_BOOK 关系中删除此订单信息。

从关系中我们可以看到,这个特定的订单包含名为“IT”的书籍信息。因此,从关系中删除此记录将导致“IT”书籍信息的丢失。这可能导致重要信息的丢失,因为它是唯一包含“IT”书籍信息的记录。但是,如果尝试从关系中删除任何其他记录,则不会引起问题,因为它仍然包含其他记录中书籍的信息。

例如: 删除订单号 = 4154 的记录,如下图所示:

订单号书名数量价格
4253C15175
4253数据库20225
4256C50175
4186数据库15225
NULL操作系统30300

表现出这种不良性质的关系被称为存在删除异常。

更新异常: 修改关系中的某些值也可能很麻烦。假设如果书籍 C 的价格修改为 190,那么所有引用这本书的元组都必须更新,而多次更新总是伴随着一些不一致的风险。

在 ORDER_BOOK 关系中,更新似乎非常容易,因为它只包含两个 B_price 为 175 的元组。但如果关系中包含数千个元组,其中包含大量冗余数据,则更新可能导致不一致,因为人容易犯错误。

表现出这种不良性质的关系被称为存在更新异常。

以上考虑得出结论,1NF 中的关系具有不良的数据操作属性,因此将关系规范化为 1NF 不会终止逻辑数据库设计。需要进一步的转换才能消除原始关系中的此类异常。这引入了第二范式的概念。


下一个主题DBMS 2NF