0

这是一个简单的问题,但我想我总是用错了方法。

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

属性表也必须接收 Page_Id?

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


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

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

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

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

4

3 回答 3

2

这是那些“取决于”情况之一 -从逻辑上讲,您不需要将值存储在 中Attribute,因为您可以通过加入来获取此信息Tag

但是,在某些情况下,无需加入 to 即可从to “跳转”可能对您很有用。在这种情况下,您可以包含in ,但您应该添加额外的约束以确保它不会与存储在 中的值不一致。AttributePageTagPage_IdAttributeTag


您可以通过在其中声明两个键来强制实现这种一致性Tag——您定义的常用键(例如Tag_Id),以及 and 上的超级Tag_IdPage_Id。然后,您将声明一个Attribute包含列的外键约束,并引用此超键。无论您是这样做而不是外键约束Tag_Id,还是除此之外,也可能是偏好/风格的问题。


如果Tags 可能会更改Pages,那么您通常会将超键的外键声明为UPDATE CASCADE发生 an 的外键 - 这样,如果表中发生Page_Id更改,则Tag该更改将自动应用于Attribute表中。

于 2012-04-19T12:22:28.623 回答
1

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

于 2012-04-19T12:24:01.770 回答
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 -> tag_name。(除非你想伤害自己,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 中。

因此,如果您对起始表进行规范化,您最终会得到“最后一个”表中的 page_id。(顺便说一句,它不再是一个真正的属性表了,是吗?)

于 2012-04-22T03:25:53.230 回答