了解数据库规范化 - 第二范式 (2NF)

Understanding Database Normalization - Second Normal Form(2NF)

我一直在从 "Fundamentals of Database Systems by Elmasri and Navathe (6th edition)" 学习归一化,但我无法理解以下有关 2NF 的部分。

下图是教材中2NF下给出的例子

候选键为{SSN,Pnumber} 依赖项是 SSN,Pnumber -> hours, SSN -> ename, pnumber->pname, pnumber -> plocation

正式定义:

A relation schema R is in 2NF if every nonprime attribute A in R is
fully functionally dependent on the primary key of R.

比如上图:

如果假设,我定义了一个额外的函数依赖 SSN -> hours,然后取两个函数依赖,

{SSN,Pnumber} -> hours and SSN -> hours 

关系不会是 2NF,因为现在 SSN ->hours 现在是部分函数依赖,因为 SSN 是给定候选键 {SSN,Pnumber} 的真子集。

查看关系及其在 2NF 上的一般定义,我假设上述关系在 2NF

就我的理解以及我如何理解 2NF 是什么,

A relation is in 2NF if one cannot find a proper subset (prime attributes)
of the on the left hand side (candidate key) of a functional dependency 
which defines the NPA(non prime attribute). 

我的第一个问题是,为什么上面的关系不在 2NF 中? (教科书已将上述关系视为不在2NF中)

然而,在本章开头定义了一种非正式的方法(根据教科书的步骤,不知道规范化的普通人可以采取这些步骤来减少冗余)是:

■ Making sure that the semantics of the attributes is clear in the schema
■ Reducing the redundant information in tuples
■ Reducing the NULL values in tuples
■ Disallowing the possibility of generating spurious tuples

提到的指引如下:

我的第二个问题是,如果考虑到上面描述的步骤,并考虑为什么下面的关系不在2NF中,你是否假设下面的函数依赖,这是,

{SSN,Pnumber} -> Pname
{SSN,Pnumber} -> Plocation
{SSN,Pnumber} -> Ename

使关系分解正确?如果假定的函数依赖不正确,那么导致关系不满足 2NF 条件的因素是什么?

从一般的角度来看...因为 table 包含不止一个主要属性并且存储的信息与员工和项目信息有关,可以指出那些需要被分开,因为 Pnumber 是复合键的主要属性,所以可以以某种方式直观地猜测冗余。这是因为我们知道属性的语义。

如果将属性替换为 A、B、C、D、E、F 会怎样

我的第三个问题是,功能依赖性是否基于"functionalities of database and a database designer having domain knowledge of the attributes"预先确定?

因为基于给定点的数据和关系状态,功能依赖性可能会发生变化,在一个状态下有效的功能依赖性可能会在某个状态下失效 state.In 一般而言,这可以用于任何非主要属性确定非主要属性。

正式定义:

A functional dependency, denoted by X → Y, between two sets of
attributes X and Y that are subsets of R specifies a constraint on the 
possible tuples that can form a relation state r of R. The constraint is     
that, for any two tuples t1 and t2 in r that have t1[X] = t2[X], they must 
also have t1[Y] = t2[Y].

那么预定义函数依赖不会是错误的,因为在任何给定点都不能概括关系状态吗?

如果我对事物的基本理解一开始就存在缺陷,请原谅我。

一个table可以说是2NF,如果主键是由多列组成的,并且如果对于每一行这些列被连接成一个字符串,那么结果列将有资格作为主键。或者,单列主键也符合 2NF 条件。

在这种情况下,同一名员工可能有多个 phone 号码 (PNUMBER),因此您不能拥有包含 phone 号码的复合主键。

Why is the above relation not in 2NF?

你的2NF的original/first/informal "definition"是乱码,没有帮助。甚至教科书中的引用也是错误的,因为 2NF 不是根据 "the PK (primary key)" 定义的,而是根据所有 CK(候选键)定义的。 (如果只有一个 CK,他们的定义是有意义的。)

A table 在 CK 上没有非素数属性的部分依赖时属于 2NF。即,当非素数属性的行列式不是 CK 的 proper/smaller 子集时。即当每个非素数属性在功能上完全依赖于每个 CK 时。

这里唯一的 CK 是 {Ssn, Pnumber}。但是 {Ssn} 和 {Pnumber} 中有 FD(函数依赖),它们都是 CK 的较小子集。所以原来的table在2NF中是不是.

If the above statement is taken into account, do you assume the following functional dependencies

so won't the same process of the decomposition shown based on the informal way alone be difficult each time such a case arrives?

A table 包含使某些 谓词(由列名参数化的语句模板)变成真实 命题 的行(陈述)。给定业务规则,只会出现某些业务情况。然后给定 table 谓词,从业务情况中给出 table 值,只能出现某些数据库值。这导致某些 table 具有某些 FD。

但是,给定一些成立的 FD,我们可以正式使用 阿姆斯特朗公理 来获得所有其他也必须成立的 FD。所以我们可以使用非正式和正式的方式来找出持有和不持有的 FD。

公理中还有 shorthand 规则。例如,如果一组属性在每个元组中具有不同的子行值,那么它的每个超集也是如此。例如,如果 FD 成立,则其行列式的每个超集决定其确定集的每个子集。例如,超级密钥的每个超集都是超级密钥,并且 CK 的适当子集都不是 CK。还有算法。

Are functional dependencies pre-determined based on "functionalities of database and a database designer having domain knowledge of the attributes" ?

规范化时,我们关心的是无论业务情况如何(即数据库状态如何)都适用的 FD。根据 table 谓词和可能的业务情况,每个业务的每个 table 都可以有自己特定的 FD。

PS 当它们的定义是根据现实世界来定义时,根据现实世界来做 "make sense" 正式的事情。例如,将谓词应用于所有可能的情况以获得所有可能的 table 值。但是,一旦您获得了必要的正式信息,就只能使用正式的定义和过程。例如,确定 FD 对 table 成立,因为它包含每个可能的 table 值。

so would any general table be in 2NF based on a solo condition of a table having a composite primary key?

5NF 中有 tables(因此所有较低的 NF)具有各种复合和非复合 CK 的混合。 PK无所谓

经常错误地说没有复合 CK 就保证 2NF。没有复合键的 table 并且 {} 没有确定任何属性 在 2NF 中。但是,如果 {} 确定一个属性,则它是 any/every CK 的 proper/smaller 子集,具有任何属性。 {} 在每行必须具有相同的属性值时确定该属性。

Why is the above relation in 2NF?

EP1、EP2 和 EP3 在 2NF 中,因为对于每一个,密钥标识非密钥。任何键的任何部分都不能标识任何非键的任何部分。这就是 对于 r 中具有 t1[X] = t2[X] 的任意两个元组 t1 和 t2 的含义,它们也必须具有 t1[Y] = t2[Y]。

相比之下,您可能会说 EMP_PROJ 是过度指定的。如果ssn识别,ename(如文中所说),那么{ssn,pnumber}的组合就太多了。存在键 {ssn,pnumber} 的子集,它标识非键 {ename} 的一部分。如 EP1、EP2 和 EP3 所示,这种情况不会发生在符合 2NF 的 table 中。

Are functional dependencies ... based on ... domain knowledge of the attributes?

强调,是的!这就是他们的全部基础。 DBMS 只是一个逻辑机器。 "employee" 和 "hours" 的想法不存在。数据库设计者选择定义 table 来模拟一些真实世界 论域 ,并为列赋予意义。他给 XY 中的属性(上图)命名。他根据正在建模的宇宙的真实情况来决定哪些列用于标识行。

if a table has a composite primary key, regardless of the functional dependencies is not in 2NF?

没有。请记住,2NF 是根据 FD 定义的。说符合其中的 2NF "regardless" 意味着什么?

键中的列数无关紧要。它是一些集合,X,识别补集,Y

我不确定我是否完全理解你的问题,但我会尝试解释一下。

你关于 2NF 的第一个陈述:

a relation is in 2NF if one cannot find a proper subset on the left hand side of a functional dependency which defines the NPA

是正确的,你的推测也是如此

if {SSN,Pnumber} -> hours and SSN -> hours then this relation wont be in 2NF

因为这意味着您可以单独从 'SSN' 确定 'hours',因此使用复合键 {SSN,Pnumber} 确定 'hours' 将是多余的,因此违反了2NF 要求。

您所说的 FD 左侧通常称为键。您使用密钥查找相关数据。为了保存 space(并降低复杂性),您应该始终尝试找到一个最小的密钥,并尽可能将较大的 table 分解成较小的密钥,这样您就不必将信息保存在比必要更多的地方。这就是范式归一化的全部内容,经过大约半个世纪的研究,已经发展出关于这个问题的实质性理论,并从中结晶出一些规则,如 1NF、2NF、3NF 等

你的第二个问题让我很困惑,因为从你说的来看,你似乎已经明白了这一点。 会不会对 FD 有一些混淆?从图中看,好像是这样定义的:

{SSN,Pnumber} -> 小时数
{SSN} -> 姓名
{Pnumber} -> Pname,Plocation

就像下面三个 table 被建模一样,它们加在一起构成了上面建模的关系 (table)。 因此,在第一个 table 中,您需要复合键 {SSN,Pnumber} 来访问关系中的任何数据(在 table 中搜索),而对于大多数字段。

现在,我不确定 table 在现实生活中会实现什么目的。虽然这在形式上不是必需的,但只要给出 FD,就可能更容易想象为什么设计会受益于规范化。

让我们今天来记录一些组织中每个项目每个员工的工作时间。 SSN 标识员工,(其姓名也存储为 ename,因为它更容易记住,但可能重复),Pnumber 标识项目,出于同样的原因,名称和位置也存储很多。

然后,如果您作为经理需要注册一名员工在某个项目上又工作了几个小时,您可以在您的设备上使用您的经理应用程序,这反过来会无缝更新 tables(您不能指望管理者理解规范化的逻辑)

然而,在幕后,它相当于一些查询,在 SQL 中,这将是一个 'INSERT' 语句,它向相关的 table(s) 添加了另一行。

现在你可以看到,在上面的 table 中,你必须插入所有的六个属性,而下面的规范化 tables,你只需要添加一行到table EP1,由三个属性组成。在一个每周有数千名员工提交工作表的大型组织中,这将很快成为存储需求的巨大差异。这有很多好处,也许是最重要的蜜蜂搜索速度。

你的第三个问题我恐怕一点都不懂。在某种程度上,您可以说,一旦您决定要将哪些数据保存在数据库中,FD 就已预先确定。 FD 不应该改变。在数据库中建模时,它们不会改变。如果你后来发现你会改变设计,那将是与新 FD 的新关系。

您似乎从某处引用的文字只是说,如果您有 FD X -> Y(X 给出或确定 Y),那么如果您在该关系中有任何两个元组(记录)(table) 具有相同的 X 值,它们也必须具有相同的 Y 值。或者在我们的示例中,如果某处的 Pnumber 的值为 888,则 Pname 为 'Battleship' 并且 Plocation 为 'Kitchen Sink',那么如果在其他地方(一些其他记录)使用了 Pnumber 888,那么 Pname 也必须是 'Battleship' 并且 Plocation 必须是 'Kitchen Sink' 因为 Pname 和 Plocation 在功能上依赖于 Pnumber.

现在那几乎是你教科书中的另一章,或者什么?希望它能有所帮助,因为我花了一些时间来写:-)