数据库设计:循环依赖

时间:2009-09-07 01:52:18

标签: database-design circular-dependency

想象一下以下数据库:

表'公司'有字段ID,名称和flagship_product_id。 表'产品'包含字段ID,名称和company_id。

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

使用MyISM等存储引擎时,上述情况应该没有任何问题,但使用InnoDB等引擎时,插入新数据时会出现问题。

除了允许初始INSERT的NULL关系外,有什么好的解决方案?

总而言之,必须 拥有一个旗舰产品。

7 个答案:

答案 0 :(得分:5)

你要么必须在flagship_product中允许NULL,要么重新考虑如何建模这种情况。考虑将flagship_product放在产品上作为布尔字段。然后你没有循环依赖。或者在产品上有一个product_type字段,该字段可能包含FLAGSHIP或NORMAL或OBSOLETE等值。当然你必须强制执行,但在过去我发现它是解决这类问题的一个更清洁的解决方案。

答案 1 :(得分:3)

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

COMPANIES

  • COMPANY_ID pk

产品

  • PRODUCT_ID(pk)
  • COMPANY_ID(fk)

FLAGSHIP_PRODUCTS

  • COMPANY_ID(pk,fk)
  • PRODUCT_ID(fk)

PRODUCTS表格中创建FLAGSHIP列并不能确保只有一种产品是给定公司的旗舰产品,因为:

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

答案 2 :(得分:2)

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

该联盟中没有一个SQL系统可以播放。

修改

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

答案 5 :(得分:0)

以下是可能解决方法的概述。我不确定这个适合的Kludge量表有多高,但它就在那里。

  • 创建数据库
  • 创建客户和产品表
  • 在每个中插入一个占位符或“虚拟”行,配置为互相引用
  • 在之间建立FK约束 表

此后,无论何时创建客户端或产品,如果尚未创建正确引用的产品/公司,您将新项目初始化为指向虚拟平台。接下来输入该项目,然后通过更新第一个条目来完成。

好处是,一旦你的数据库初始化程序完成,你就拥有了绝对的参照完整性 - 你只能在大概非常控制的情况下运行一次,所以仔细观察并确保它没有失败了!不缺点是,您现在每个表中都有一个“额外”项目,使您的系统变得混乱。

答案 6 :(得分:0)

您需要通过延迟一个参照完整性约束来打破周期,直到事务结束。

请谷歌“初步推迟推迟”。

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