【问题标题】:Cycle in ER diagram: Bad design? BCNF?ER图中的循环:糟糕的设计? BCNF?
【发布时间】:2013-06-15 08:24:42
【问题描述】:

我想在我的数据库中对语言语法树进行建模。在我的设计中,语法树由内部节点和终端节点组成;这两种类型的节点都是弱实体类型,由它们所属的语法树标识。语法树本身也是弱实体;它们由它们要表示的句法结构的句子来识别。一个给定的句子可能有不止一个语法树。 终端节点可以与(1:m-relation)来自其句法树标识的句子中的标记相关联。标记也是由它们所属的句子识别的弱实体。

总的来说,在将我的 ER 图转换为关系模式后,我的一些关系模式看起来像这样(简化):

句子(sentenceID)

syntaxTree(sentenceID, treeDiscr)

token(sentenceID, tokenDiscr)

terminalNode(sentenceIDFromTree, treeDiscr, nodeID, sentenceIDFromToken, tokenDiscr)

如您所见,terminalNode 的关系模式包含两个外键,每个外键引用一个 sentenceID:一个保存句法树表示的句子的 ID,一个保存标记所属的句子的 ID。当然,这些 sentenceID 的值总是需要相同的。因此,对于 terminalNode,以下两个函数依赖成立:

sentenceIDFromTree -> sentenceIDFromToken

sentenceIDFromToken-> sentenceIDFromTree

对于这些依赖项,右侧都不对应左侧的子集,即它们不是微不足道的;它们的左侧也不对应于超级键——即关系模式不在 BCNF 中。为了使关系模式在BCNF中,我认为我可以将sentenceIDFromTree和sentenceIDFromToken合并为一个属性;毕竟,无论如何,这两个属性总是需要具有相同的值。据我了解,在 SQL 中,我不能直接让一个外键同时引用多个表,因此我可能不得不使用一些额外的触发器来确保 syntaxTree 和令牌表都被引用由单个句子ID。 由于我在数据库设计方面没有太多经验,并且诚然不知道什么是“好的数据库设计”,我现在想知道我是否应该真正合并两个外键,或者保持我的设计不变(或者可能还有更多处理这个问题的方法?)。此外,我担心整个问题可能表明我的概念设计确实有问题,但我不知道如何以不同的方式对这种情况进行建模。任何帮助将不胜感激。

【问题讨论】:

  • 有 terminalNode(sentenceId, treeDiscr) -> syntaxTree 和 terminalNode(sentenceId, tokenDiscr) -> token?或者是 sentenceIDFromToken 和 sentenceIDFromTree 可以不同的情况吗? (如果是,为什么?)
  • 不,sentenceIDFromToken 和 sentenceIDFromTree 必须始终保持相同的值;即,一个终端节点只能与相应语法树相关联的句子中的一个标记相关联。这就是为什么我想出了将这些属性合并为一个的想法。
  • 这听起来不错。在两个关系之间共享同一列应该没有问题;只要它只有一列。当然,可能会有一个约束(sentenceIDFromTree = sentenceIDFromToken),但可以通过 sentenceId 参与两个 FK 关系来消除。

标签: sql database database-design foreign-keys database-normalization


【解决方案1】:

你写道:

在 SQL 中我不能让一个外键同时直接引用多个表

这里有些不精确,这是您问题的根源。外键只能引用一个表。但是,单个表列可以是一个或多个外键的一部分。

因此,正确的设计是:

  • terminalNode 中只有一个sentenceID
  • 有两个外键,都包括sentenceID

这种重叠确保了两个父母之间的关系是正确的。

【讨论】:

  • 谢谢,我显然已经开始混淆列和外键,它们可以成为我脑海中的一部分。
猜你喜欢
  • 2012-02-28
  • 2017-06-11
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 2012-09-06
  • 2011-08-01
相关资源
最近更新 更多