Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 数据库设计:循环依赖_Database Design_Circular Dependency - Fatal编程技术网

Database design 数据库设计:循环依赖

Database design 数据库设计:循环依赖,database-design,circular-dependency,Database Design,Circular Dependency,想象一下以下数据库: 表“公司”包含字段id、名称和旗舰产品id。 表“products”包含字段id、名称和公司id 一个公司必须有一个旗舰产品(1:1关系),所有产品都有一个公司(1:N关系) 当使用MyISM之类的存储引擎时,上述场景应该不会有任何问题,但当使用InnoDB之类的引擎时,插入新数据时会出现问题 除了允许初始插入为空关系外,还有什么好的解决方案 总而言之,一家公司必须有一个旗舰产品。我不知道那个数据库引擎,但是,在原子插入和更新操作期间,搜索一种临时挂起数据一致性检查或引用完

想象一下以下数据库:

表“公司”包含字段id、名称和旗舰产品id。 表“products”包含字段id、名称和公司id

一个公司必须有一个旗舰产品(1:1关系),所有产品都有一个公司(1:N关系)

当使用MyISM之类的存储引擎时,上述场景应该不会有任何问题,但当使用InnoDB之类的引擎时,插入新数据时会出现问题

除了允许初始插入为空关系外,还有什么好的解决方案


总而言之,一家公司必须有一个旗舰产品。

我不知道那个数据库引擎,但是,在原子插入和更新操作期间,搜索一种临时挂起数据一致性检查或引用完整性的方法。

为什么不将旗舰产品字段作为布尔值放入products表中。。。你可以索引它和companyid并快速查找

你要么在旗舰产品中允许空值,要么重新考虑如何模拟这种情况。考虑将旗舰产品放在产品上作为布尔字段。那么你就没有循环依赖了。或者在产品上有一个product_type字段,该字段可能具有旗舰、普通或过时等值。当然,您必须强制执行这一点,但在过去,我发现它是解决此类问题的更为干净的解决方案。

我建议使用以下数据模型:

公司

  • 公司ID pk
产品

  • 产品标识(pk)
  • 公司ID(fk)
旗舰产品

  • 公司ID(主键,fk)
  • 产品标识(fk)
产品
表中创建旗舰列不会确保只有一种产品是给定公司的旗舰产品,因为:

  • 旗舰列上的唯一键要求值彼此不同
  • 检查约束只是可接受值的列表

能够正确处理此类情况的智能和功能强大的产品只有完全接受/实施多重分配概念的系统

在这个联盟中没有一个SQL系统

编辑


SQL系统有延迟的约束检查,但使用它可能会变得混乱。

下面是一个可能的解决方法的概要。我不确定这在乱七八糟的尺度上有多高,但它在上面

  • 创建数据库
  • 创建客户机和产品表
  • 在每行中插入一个占位符或“虚拟”行,配置为相互引用
  • 在对象之间建立FK约束 桌子
此后,每当创建客户或产品时,如果尚未创建正确的引用产品/公司,则初始化新项目以指向虚拟产品持有人。接下来输入该项,并通过更新第一个条目来完成


好处是,一旦数据库初始化例程完成,您就拥有了绝对的引用完整性——而且您只在假定非常受控的情况下运行一次,所以请密切关注它并确保它不会失败!不利的一面是,现在每个表中都有一个“额外”项使系统混乱。

您需要通过将一个引用完整性约束推迟到事务结束来打破这个循环

请谷歌搜索“最初推迟”



(不确定InnoDB是否支持此功能)

在MySQL上,它是
设置外键检查=0
,但这是唯一的方法吗?如果你坚持这种设计,我很确定这就是路线。如果您只在手术期间这样做,为什么会不受欢迎?我想我知道是什么让你不舒服-你想让它更干净。不幸的是,我认为关系数据库不善于表达这种关系。有些事情必须在应用层实施。:-)我认为这是我唯一的选择,我需要加强这种关系,我找不到任何其他解决办法。我选择这一个是因为它是唯一一个允许我保持理智的关系,而不是程序错误可以破坏东西的“标志”。这没有任何理智的东西。。。一般来说,如果必须暂停检查,则模型将被破坏。我并不是说它不起作用,但是一旦你暂停了对insert的检查,就没有什么强迫该字段被设置为任何内容了。。。如果在产品表中设置一个标志,您会遇到与此相同的程序问题。您可以轻松地更进一步,创建一个产品属性表,列出与产品相关的属性,其中一个可以是“旗舰”。如果需要,这允许多个属性。但这意味着一家公司可能有多个旗舰产品,这是不需要的。正如我所说,必须强制执行。您将如何强制执行?检查约束不起作用,也不能使用唯一键。您可以在应用程序级别(我的首选项)或使用表上的触发器强制执行它。索引对业务规则没有任何影响-谁投了赞成票?!此型号要求旗舰产品上的
唯一(公司id、产品id)
,对吗?所以它基本上是一个1:1的数据透视表(奇怪的…。@strager:因为pk是
公司ID
,所以一家公司只能有一个条目-在
产品ID
上不需要唯一的键,那么我如何强制一家公司有一个旗舰产品呢?@rexem,啊,真的@莉拉努娜,不知道。此解决方案仅强制一个或不强制一个。嗯…这仍然是一种循环关系。。。您刚刚向混合中添加了另一个表。这比允许null-null作为不可见的保留占位符好吗?引用伪行或占位符行是使用null外键引用的标准替代方法