第三范式 - 两个外键之间的传递依赖?

时间:2013-09-24 22:40:08

标签: relational-database database-normalization functional-dependencies 3nf

我正在创建一个包含我拥有并阅读的书籍的数据库。我想跟踪我拥有和阅读的书籍(或“标题”),以及我拥有和阅读的那本书的版本(或“物理装订纸”)。

书籍和版本是多对多的。我拥有“美国民主”一书的多个版本。我还拥有一个名为“海明威”的版本,其中包含几本书(或“标题”),其中一本名为“For Bell of Bell Tolls”。

因此,我需要一本书和版本之间的桥梁。我的表是:

书(book_pk *,标题)
版(edition_pk *,ISBN,年)
Book_Edition(book_fk,edition_fk)

我认为Book_Edition表包含复合主键是正确的。

现在,我正在处理我的Read表,其中包含我已阅读的书籍以及我阅读它们的日期。到目前为止我的阅读表包含:

阅读(read_pk,日期,备注)

但是,我现在需要将Read表与我的书籍和版本联系起来。在我看来,book_fk和edition_fk在这种情况下是过渡依赖的。那么我如何遵守第三范式?

选项1:
将Read表修改为:Read(read_pk,date,note,book_fk,edition_fk)

选项2:
将Book_Edition表修改为:Book_Edition(book_edition_pk,book_fk,edition_fk)
将Read表修改为:Read(read_pk,date,note,book_edition_fk)

选项3: ???

任何见解都将受到赞赏。如果在其他地方得到了治疗,请道歉;我看到一些看起来很有前途的帖子,但作为一个亲戚n00b,我无法破译它们并将它们应用到我的情况中。


每个sqlvogel编辑:
让我尝试识别依赖关系 - 也就是说,我试图确定如果字段A被更改的地方,那么字段B必须或可能会改变。我认为我发现这很困难,因为书籍(“标题”和“装订纸”的集合)本身就是永久性的。如果存在数据输入错误,我唯一希望编辑标题,ISBN或年份字段的时间。如果输入的特定版本_pk的ISBN不正确,那么同一版本_pk的年份也可能输入不正确,但这是一个依赖项吗?

关于阅读表,我认为情况类似。每次阅读书籍时都会创建记录,理论上从不编辑。我想确定在特定日期阅读的书籍和版本。如果存在数据输入错误,则可能会影响一个或多个字段。特别是,如果输入了错误的book_fk,则更有可能输入了错误的edition_fk。再一次,这是我应该担心的依赖吗?

在考虑依赖关系时,我还需要考虑其他什么吗?

2 个答案:

答案 0 :(得分:4)

选项1:阅读(read_pk,date,note,book_fk,edition_fk)

假设:

{read_pk}->{date,note,book_fk,edition_fk}
{read_pk} is the primary key of Read.

为了举例,假设{book_fk,edition_fk}->{date},意味着每本书只读一次(每本书/版只有一个日期)。如果您没有将{book_fk,edition_fk}作为候选键,则{book_fk,edition_fk}->{date}将是违反3NF的非键依赖项的示例,因为行列式不是键。即使您用{book_edition_fk}代替{book_fk,edition_fk},情况也是如此。即就3NF而言,您的选项2显然与选项1相同。

由于您没有指定任何依赖关系,我刚刚将此作为示例。我不能说这些依赖关系是否正确描述了你的情况。您自己需要确定实际应该生效的依赖项。

答案 1 :(得分:-1)

传递依赖性要求dependent属性是非键属性。由于您关注的两个属性是外键,因此您的结构中没有传递依赖性问题。

您无需更改原始设计。