Database 表必须接收外键吗?
这是一个简单的问题,但我想我总是用错了方法 我有三个名为Page->Tag->Attribute的表。标记表接收页面Id(外键),属性表接收标记Id(外键) 属性表也必须接收页面Id? 我从来没有这样做过,但我看到一个数据库SQL生成器可以这样做,所以,我意识到这使所有的工作变得更容易,但这也是正确的方法吗Database 表必须接收外键吗?,database,normalization,rdbms,Database,Normalization,Rdbms,这是一个简单的问题,但我想我总是用错了方法 我有三个名为Page->Tag->Attribute的表。标记表接收页面Id(外键),属性表接收标记Id(外键) 属性表也必须接收页面Id? 我从来没有这样做过,但我看到一个数据库SQL生成器可以这样做,所以,我意识到这使所有的工作变得更容易,但这也是正确的方法吗 编辑表的详细信息:页面表包含HTML页面和一些属性,如内容、标题、doctype和HTML页面的所有其他单个元素 标签表包含HTML页面的HTML标签,其中包含标签(a、p、br、h1、标
编辑表的详细信息:页面表包含HTML页面和一些属性,如内容、标题、doctype和HTML页面的所有其他单个元素 标签表包含HTML页面的HTML标签,其中包含标签(a、p、br、h1、标题等)和整个标签等信息 属性表包含标记的所有属性,就像一个带有键和值的映射,其中每个条目都是一个属性和一个值 页面包含多个标记(1:N),标记包含多个属性(1:N)。每个表都包含一个唯一的标识。这是一种“视情况而定”的情况-从逻辑上讲,您不需要将值存储在
属性中,因为您可以通过加入标记来派生此信息
但是,在某些情况下,您可以从属性
跳到页面
,而不必加入标记
,这可能会很有用。在这种情况下,您可以在属性
中包含页面Id
,但您应该添加额外的约束,以确保它与标记
中存储的值不一致
您可以通过在Tag
中声明两个键来实现此一致性-您定义的常用键(例如Tag\u Id
),以及Tag\u Id
和Page\u Id
上的超级键。然后在属性
中声明一个包含两列的外键约束,并引用此超键。您是否这样做,而不是仅对标记Id执行外键约束,或者除此之外,还可以执行外键约束,这也可能取决于您的偏好/风格
如果标记
s很可能会更改页面
s,那么您通常会将超级键的外键声明为发生更新级联
的外键-这样,如果标记
表中的页面Id
发生更改,该更改将自动应用于属性表中。这是一种“视情况而定”的情况-从逻辑上讲,您不需要将值存储在属性中,因为您可以通过加入标记来获取此信息
但是,在某些情况下,您可以从属性
跳到页面
,而不必加入标记
,这可能会很有用。在这种情况下,您可以在属性
中包含页面Id
,但您应该添加额外的约束,以确保它与标记
中存储的值不一致
您可以通过在Tag
中声明两个键来实现此一致性-您定义的常用键(例如Tag\u Id
),以及Tag\u Id
和Page\u Id
上的超级键。然后在属性
中声明一个包含两列的外键约束,并引用此超键。您是否这样做,而不是仅对标记Id执行外键约束,或者除此之外,还可以执行外键约束,这也可能取决于您的偏好/风格
如果标记
s很可能会更改页面
s,那么您通常会将超级键的外键声明为发生更新级联
的外键-这样,如果标记
表中的页面Id
发生更改,该更改将自动应用于属性表中。这是不必要的,如果您正在严格规范化,则答案应该是“页面id不应位于表属性上”。但是通常需要(用于报告或加速某些操作)对表进行反规范化,例如,在表上添加一个字段,您可以通过简单的查询(如您的示例中)获得该字段。这是不必要的,如果您严格规范化,那么答案应该是“页面id不应位于表属性上”。但是通常需要(用于报告或加速某些操作)对表进行反规范化,例如在表上添加一个字段,您可以通过简单的查询(如您的示例)获得该字段。我没有看到您的表结构,因此我必须继续您的描述。那总是有风险的
如果您的描述意味着页面和标记之间存在1:M关系,标记和属性之间存在1:M关系,那么起始关系的示例数据应该与下表类似。(起始关系总是包含所有表的所有属性。)
- page_id应该标识一个页面
- tag_id用于识别标签,以及
- 标记的属性取决于该标记显示的页面。(因此标记和属性之间没有多值依赖关系。)
根据您的描述,我们已经知道页面id->页面名称和标签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
表A中还保留哪些函数依赖项、多值依赖项或联接依赖项?没有。唯一的候选键是{page\u id,tag\u id,attr\u id}。我很确定这三张桌子都至少有5NF
因此,如果对起始表进行规范化,则最终会在“last”表中显示页面id。(顺便说一句,它不再是一个真正的属性表了,是吗?我还没有看到y
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