我的数据库设计目前处于第3NF阶段。关注的问题是外键,在某些情况下是复合键。
我的问题是:
如果与复合键/外键关联的属性不依赖主键,是否可以移动复合键和/或外键来创建其他表?
我认为答案是肯定的,因为这个链接:
外键是否包含在第三范式中?
最佳答案:仅仅因为它是外键并不意味着它也不能被视为主键的属性。事实上它是一个外键开头意味着它定义了与另一个表的关系,因此不会违反[3] 3NF。
- TheMadProfessor
https://answers.yahoo.com/question/index?qid=20081117095121AAXWBbX#
这让我想知道我正在处理的当前正常化阶段是否实际上是3NF。
我不能在这个问题上发表我的表格,因为我是新人并且没有足够的分数。
答案 0 :(得分:4)
在纯关系数据库理论中,没有什么能阻止你拥有复合主键(PK),并且你可以拥有引用它们的外键(FK),而且那些FK也必然是复合的。某些软件对复合键有困难,因此您经常会发现人们添加了一个ID列,其中包含一个自动生成的数字,然后将其指定为表的PK。然后,其他表可以具有引用(简单)ID列的(简单)FK。一个并不罕见的错误是忘记原始复合PK仍然是候选密钥(CK),其唯一性应由DBMS强制执行,并在表上具有唯一约束;它成为替代钥匙(AK)。
CKs,AKs和PKs系统的工作原理如下:
考虑下表:
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL PRIMARY KEY
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE,
name CHAR(20) NOT NULL UNIQUE,
atomic_weight DECIMAL(8,4) NOT NULL,
period SMALLINT NOT NULL
CHECK (period BETWEEN 1 AND 7),
group CHAR(2) NOT NULL
-- 'L' for Lanthanoids, 'A' for Actinoids
CHECK (group IN ('1', '2', 'L', 'A', '3', '4', '5', '6',
'7', '8', '9', '10', '11', '12', '13',
'14', '15', '16', '17', '18')),
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
atomic_number
,symbol
和name
中的每一个都是候选键。对于化学,symbol
作为主键是最方便的;对于物理学来说,atomic_number
是最方便的。与同位素等相关的表格引用了atomic_number
列,但与化合物相关的表格引用了symbol
列。这里的三个CK都很简单;另一方面,同位素表有一个化合物PK,由元素的原子序数(质子数)和中子数组成。
回到你的问题,你的数据很可能是3NF,或更可能是BCNF(正式强于3NF)。
在我们评估您的设计之前,您必须向我们展示您的表模式并指定适用于列的约束(函数依赖性等)。但是,你所描述的并没有什么,先验地阻止它被很好地规范化。
答案 1 :(得分:3)
我不确定我理解你的问题。如果你问,“你能否在没有违反3NF的情况下在表中使用外键?”答案绝对是肯定的。没有关于任何正常化阶段的事情说你应该消除外键。实际上,除了最简单的数据之外,几乎不可能在不使用外键的情况下对所有数据进行标准化。
**更新**
好吧,也许现在我理解你的问题了,但我认为你已经为自己解答了。是的,在完全规范化的数据库中,您不应该具有非密钥依赖性。如果您的FK不依赖于PK,则应将它们移动到另一个表。
举一个简单的例子,假设您想要跟踪人们,他们居住的城市以及该城市所在的国家。因此,对于您的初稿,您可以制作以下结构:(星号标记PK。 )
Person (person_id*, person_name, city_id, country_id)
City (city_id*, city_name)
Country (country_id*, country_name)
这不规范化。无论我们所谈论的那个城市的居民是哪个城市都在同一个国家。当我们谈论皮埃尔时,巴黎不在法国,但在德国,当我们谈论弗朗索瓦时,巴黎。 (如果有两个同名的城市,当然那些城市不同,应该有不同的记录。我想一个城市可以跨越国界,但为了我们的目的,让我们假设如果有,我们认为它是两个城市他们肯定会有不同的城市政府,不同的邮政系统等等。所以我们有一个非关键的依赖。 country_id取决于city_id,而不取决于person_id。
因此,要规范化此架构,我们应该将country_id移动到一个仅依赖于PK的表。据推测,城市表:
Person (person_id*, person_name, city_id)
City (city_id*, city_name, country_id)
Country (country_id*, country_name)
答案 2 :(得分:0)
您是否了解FD(功能依赖)是什么? FD是两个属性集之间带箭头的表达式。给定一个表和FD,表示FD保存在表中或表中有FD或表满足FD表示第一个属性集的所有子行对第二个属性集都显示相同的子行。
您是否理解规范化涉及CK(候选键)?独立于规范化,我们可以将一个CK称为PK(主键),而将其他AK称为(备用键)。
你明白FK(外键)是什么吗?给定一个数据库,一个表和一个属性列表,说这个列表是一个引用某些表中某个属性列表的FK表示每个第一个表中属性的值列表也是第二个表中属性的值列表,其中这些属性构成CK(候选键)。
标准化使用FD&amp; JD(连接依赖项)通过连接它的投影来替换表。 FK(外键)与规范化无关。表格是否处于给定的NF(正常形式)和分解为给定的NF。您链接的答案还表明,FK与表格是否在3NF无关 - 首先针对特定情况,然后针对一般情况。
由于组件共享原始表中的列值,因此某些FK将来自规范化。就像各种表格及其PK,AK,CK,超级密钥,FD和&amp; JD会。这是标准化输出,而不是输入。
由于规范化通过它们的投影替换表,因此在原始和&amp;之间的列集是相同的。组件必须包含相同的子行值。这是一个EQD(平等依赖)。因此,形成CK的子行数值将具有归一化的FK。
但通常在规范化过程中,我们会看到我们想要替换一些表,这些表是与至少投影的子行的其他人一起投影的。然后,投影中的公共子行必须出现在展开的组件中,反之则不然。那是一个IND(包含依赖)。当公共列在表格中形成CK时,仍然会有FK,这是投影的超集。这样的设计变更不是标准化,它只是在标准化过程中注意到的一种变化,这种变化是由于设计错误导致所有可能的业务情况都没有记录到没有问题的设计中
&#34;化合物&#34; vs&#34;简单&#34; vs&#34;空&#34;适用于FK,PK,AK,CK(候选键)和&amp;超级钥匙,与FD&amp; JD部分。 定义将在重要时指定复合/简单/空。(例如:有时FD被放入涉及单列的规范形式。有时我们可以根据CK是否简单来轻易地推断NF持有。)< / p>
获得表后,声明(足够)约束。然后DBMS可以强制执行它们。 FK,PK,AK,CK,超级密钥,FD和&amp; JD都有相关的约束。 SQL允许您声明所有PK和&amp; AKs(通过PRIMARY KEY
&amp; UNIQUE NOT NULL
)。这些声明实际上声明了 superkeys ,当它们中没有声明更小的声明时,碰巧是CKs / PKs / AKs。类似地,SQL FOREIGN KEY
声明一个外来超级密钥,如果它实际上是一个CK,则它是FK。声明FK
s的足够链以强制执行您未声明的链。 (通过传递性。)SQL DBMS通常不会让你声明FK周期。 SQL还使您声明由FK
声明引用的超级密钥,无论这些列是否包含较小的声明超级密钥/ CK,因此必须是超级密钥。通过触发器声明或强制执行CK约束不暗示的任何FD或JD约束。 (除了CK上的一些FD周期外,5NF除去所有这些约束。)
查找学术教科书定义和算法。