【问题标题】:What are the consequences of violating a one-to-many relationship & when to use a many-to-many?违反一对多关系以及何时使用多对多的后果是什么?
【发布时间】:2016-08-31 04:36:18
【问题描述】:

考虑到订单记录的数量比标签大很多:

  1. 我已经阅读了一个 SO question's comment,其中插入 order# 68 如图所示不会造成任何麻烦,但如果我想按某些标签查询订单,多对多更合适/方便/高效,否则在一对多的情况下,必须检查每个订单以了解其标签,这是真的吗?

    • 一个。我还记得读过多对多关系在资源上的成本最高并且表现不佳,但还读过声称性能损失可以忽略不计并且不值得处理多对多孤儿记录的风险和开销关系,有什么关系吗?

    • b.根据其他阅读材料,如果不再存在多对多而是 2 个一对多表,我确信通过制作 2 个具有 FK 联合表的一对多表来建模多对多是否避免了上述多对多的缺点?

  2. 在我在另一个论坛上发布的类似问题中,有人告诉我我什至无法插入订单# 68,这样做会导致引用完整性问题,这几乎没有意义,这也是真的吗?

我想摆脱我读过的相互矛盾和自相矛盾的帖子。

【问题讨论】:

  • @leo 我为你上传了。
  • 只是为了明确一点:只有当你规范化时,你才需要一个连接表来实现多对多关系。在第二个 NF 中,您可以轻松地在数据库中使用大量冗余。关于问题:您可以插入任何不会与您的表约束和引用约束(PK、FK、UNIQUE ...)冲突的记录。一种关系表明存在 FK 约束,这将禁止插入其他带有已存在 tagId 的订单。但是,并非所有数据库都有 FK 约束(尽管它们确实加快了速度,因为 FK 列大多被索引)
  • 我建议规范化您的表并设置外键。这是您可以真正确定数据永远不会损坏的唯一方法,它可以为您节省大量编码,因为您不必检查自己的插入、更新或删除是否遵循规则,数据库可以做到。这比你快得多。你的观点 b 是正确的,这就是要走的路。

标签: sql sql-server database entity-framework


【解决方案1】:

世界是一个复杂的地方,您的问题假设所有问题都有一个答案。事实上,对于您提出的问题,答案是一对多的。

  1. 您描述的插入可能导致问题,或者它可能不会导致问题。这取决于您是否向数据库添加了规则以强制执行参照完整性。有些人喜欢做这样的事情——我不喜欢。我有一个数据模型,它说关系是一对多的,我假设人们会遵循它,因为如果他们不这样做,它就会中断。让数据库强制执行此规则只会减慢速度。在我看来,最好每年让一切都中断一次,找出问题所在,用湿面条鞭打新程序员,然后继续前进。

至于 1 的其余部分。这仅取决于您正在使用的数据的意义——一般情况下谁能说。

  1. 参见 1。是的,可以让数据库阻止您插入,但我不建议您以这种方式设置数据库。除非 Order# 是一个定义为唯一的索引 - 在这种情况下,尝试重复插入时会出错。

【讨论】:

  • 在您的数据库中没有 FK 只会导致数据库损坏,我不建议这样做。如果您删除了一个表中的一条记录,而该表中的主键在另一个表中被引用了怎么办?要么您的数据库现在已损坏,要么您必须通过检查来溢出您的代码。让数据库来做这就是它的用途。程序员不应该被追踪,数据库设计者应该被追踪。
  • @Hogan 找到“销售”标签的“订单#s”的最佳性能:1. OP 的内部连接描绘了一对多或 2. 多对连接许多连接表?
  • 如果没有 FK,您将无法进行内部连接,因为您引用的记录可能不再存在。
  • @GuidoG 你说的记录有被删除的风险,即使没有霍根提到的任何限制,我想你也会建议唯一的选择是选项 2。在我的第一条评论中8 分钟前到霍根??
  • 我的意思是,如果您不设置外键,您可以删除标签表中的所有记录而不会出错,然后您的订单表中的所有引用都已损坏,因为它们引用了标签表中不存在的记录
【解决方案2】:

根据您的图像,我会说您在 tblTAG 和 tblOrder 之间存在一对多的关系。 我在这张图片中没有看到多对多的关系,添加记录根本不会产生任何问题。

tblTAG.TagID 1 可以在 tblORDER 中多次存在,没有问题。 还有一个类似

的查询
select * from tblORDER where TagID = 1

将执行得非常快,因为 tblORDER 中的外键将创建一个索引。

那么为什么这里需要多对多关系呢?

【讨论】:

  • tagID 1 将与订单 23 和订单 68 相关联(大于 1 个订单,尽管建模为多个订单的 #one#,但本质上标签与 2 个订单相关联)。一般来说,我读过的标签通常被建模为多对多,这就是我使用这个例子的原因,但考虑到你在数据库关系决策中相当开放并且是一个经验丰富的数据库人,现在百万美元的问题是在哪些情况下会@GuidoG 使用多对多,其中一对多变体不够用,不牺牲引用完整性并将 FK 明确命名为约束?
  • 我使用多对多,规范化告诉我使用一个,它与一对多不够用无关。如果您的订单表中的每条记录都需要从标签表中引用一个标签,那么就不需要多对多。除非我弄错了,否则我可以从您的问题中的图像中弥补这一点。所以我的问题是你需要什么。每个订单都引用一个标签?这是从标签到订单的一对多和从订单到标签的一对一。我不清楚你的桌子设计需要什么。
  • 在您问题的图片中,1 和许多符号对我来说似乎是错误的,除非我理解错误。如果有,请详细说明
  • 在他的观点上,我的整个讨论都是基于这样一个概念,即一旦插入记录 68 的 2 个标签关联,这不再是一对多的,而且许多对两者都有效边,即“销售”标签与 2 个订单(#23 和 68)相关联,订单与 2 个标签(sale 和 deliv)相关联,,,在没有 (Pk | orderid | tagid) 多对-许多连接表
  • 不完全正确。您必须以不同的方式看待它,从订单的角度来看,一个订单将只有一个标签,从标签的角度来看,一个标签存在于许多订单中。所以它是从标签到订单的一对多关系和从订单到标签的一对一关系。这里不需要多对多,除非我误解了你的桌子设计
猜你喜欢
  • 2014-10-16
  • 2015-09-16
  • 1970-01-01
  • 2016-03-16
  • 2012-11-07
  • 1970-01-01
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多