表必须接收外键吗?

时间:2012-04-19 12:19:14

标签: database normalization rdbms

这是一个简单的问题,但我认为我总是使用错误的方式。

我有三个名为 Page 的表 - > 标记 - > 属性。 Tag表接收Page_Id(外键),Attribute表接收Tag_Id(外键)。

属性表也必须收到Page_Id吗?

我从来没有这样做过,但是我看到了一个数据库SQL生成器来执行此操作,因此,我意识到这会使所有工作变得更容易,但这也是正确的方法吗?


使用表格的详细信息进行编辑:Page表格包含HTML页面和一些属性,例如内容,标题,doctype以及html页面的所有其他单个元素。

Tag表包含html页面的HTML标记,其中包含标记(a,p,br,h1,title等)和整个标记等信息。

属性表包含标记的所有属性,就像带有键和值的Map,其中每个条目都是属性和值。

页面包含多个标签(1:N),标签包含多个属性(1:N)。每个表都包含唯一标识。

3 个答案:

答案 0 :(得分:2)

这是“依赖”的情况之一 - 你没有,逻辑上需要将值存储在Attribute中,因为你可以通过加入{来获得这些信息{1}}。

但是,在某些情况下,您可以有用Tag“跳转”到Attribute而无需加入{{1} }。在这种情况下,您可以在Page中添加Tag,但是您应该添加其他约束以确保它与Page_Id中存储的值不一致。


您可以通过在Attribute中声明两个键来强制执行此一致性 - 您定义的常用键(例如Tag),以及TagTag_Id上的超级键。然后,您将在Tag_Id中声明包含两个列的外键约束,并引用此超级键。无论你是仅仅Page_Id,还是仅仅Attribute的外键约束,也可以是偏好/风格问题。


如果Tag_Id s可能会更改Tag s,那么通常会将超级密钥的外键声明为Page发生的外键 - 这样,如果UPDATE CASCADE表中Page_Id发生更改,则该更改将自动应用于Tag表。

答案 1 :(得分:1)

没有必要,如果你严格规范化,那么答案应该是“page_id不应该在表格属性上”。但是通常需要(用于报告或仅加快某些操作)来对表进行反规范化,例如在表上添加一个可以通过简单查询获得的字段(如示例中所示)。

答案 2 :(得分:1)

我还没有看到你的桌子结构,所以我必须继续你的描述。这总是有风险的。

如果您的描述意味着页面和标签之间存在1:M关系,并且标签和属性之间存在1:M关系,那么起始关系的样本数据应如下表所示。 (起始关系始终包含所有表的所有属性。)我认为

  • page_id应该标识一个页面,
  • tag_id应该识别标签,
  • 标记的属性取决于标记显示的页面。 (因此不是标签和属性之间的多值依赖关系。)

    Table_A
    page_id  page_name  tag_id  tag_name  attr_id
    --
    1        page1      1       tag1      attr1
    1        page1      1       tag1      attr2
    1        page1      2       tag2      attr1
    1        page1      2       tag2      attr3
    2        page2      1       tag1      attr1
    2        page2      1       tag1      attr2
    2        page2      2       tag2      attr1
    2        page2      2       tag2      attr2
    

我们已经从您的说明中了解到page_id - > page_name和tag_id - >标签名称。 (除非你试图伤害自己,page_name - > page_id和tag_name - > tag_id。)所以让我们根据这些知识来设计新表。

Table_C
tag_id  tag_name
--
1       tag1
2       tag2

Table_B
page_id  page_name
--
1        page1
2        page2

Table_A
page_id  tag_id  attr_id
--
1        1       attr1
1        1       attr2
1        2       attr1
1        2       attr3
2        1       attr1
2        1       attr2
2        2       attr1
2        2       attr2

Table_A中保留了哪些功能,多值或连接依赖项?没有了。唯一的候选键是{page_id,tag_id,attr_id}。我很确定这三个表中至少有5NF。

因此,如果您规范化起始表,则最终会在“last”表中使用page_id。 (顺便说一句,它不再是属性表,是吗?)