DB:数据库中的循环依赖项

时间:2010-01-25 16:03:57

标签: database-design rdbms database

编辑:这是duplicate我一开始并没有找到它。

我正在为用户组事件管理构建一个网站。

Members : Name, Id  
Events : DateTime, Topic, OrganizerId (from FK to Members table)
EventRegistrations : MemberId (FK), EventId (FK)

描述(冗余):
会员可以创建和活动,并成为此活动的组织者 任何成员都可以注册事件,并创建EventRegistrations中的记录。

问题:
当我在表之间创建PK-FK依赖关系时,我收到一条错误说:

  

在表'eventregistrations'上引入FOREIGN KEY约束'reg_evt_fk'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

问题:
处理这个问题的好方法是什么?我有两个解决方案:

  1. 介绍第4个(关联)表“组织者:MemberId - > EventId”。
  2. 在其中一个依赖项上禁用CASCADE DELETE,并在DELETE操作之前以编程方式进行检查。
  3. 我正在寻找有关上述内容的建议或反馈。赞赏额外的解释/评论。

    注意:数据库是SQL Server 2008,但我认为无关紧要。

    编辑:假设删除事件 IS 所需行为(示例已简化)。

4 个答案:

答案 0 :(得分:2)

我想这不是循环依赖,而是“多级联路径”问题(不记得确切的错误信息)。

我更喜欢的解决方案是删除OrganizerId CASCADE DELETE,因为删除组织成员不应自动删除成员的事件,并将此部分实现为SP。

您仍然可以在INSTEAD OF DELETE触发器或SP中实现子记录删除。

答案 1 :(得分:2)

不确定为什么你会得到循环依赖。你确定你已经宣布与正确的忠诚度有关系吗?

你的桌子......

SQL> create table members
  2      ( name varchar2(10)
  3          , id  number not null primary key   )
  4  /

Table created.

SQL> create table events
  2      ( id  number not null primary key
  3          , datetime date
  4          , topic varchar2(10)
  5          , organizerid  number not null )
  6  /

Table created.

SQL> create table eventregistrations
  2      ( memberid  number not null
  3          , eventid  number not null)
  4  /

Table created.

SQL>

会员可以组织任意数量的活动。活动必须有一个组织者。

SQL> alter table events
  2      add constraint evt_mbr_fk foreign key ( organizerid )
  3      references members (id) on delete cascade
  4  /

Table altered.

SQL>

会员可以注册任意数量的活动......

SQL> alter table eventregistrations
  2      add constraint reg_mbr_fk foreign key ( memberid )
  3      references members (id) on delete cascade
  4  /

Table altered.

SQL>

活动可以有任意数量的注册会员......

SQL> alter table eventregistrations
  2      add constraint reg_evt_fk foreign key ( eventid )
  3      references events (id) on delete cascade
  4  /

Table altered.

SQL>

注意:我没有打算执行规则“一个成员只能为任何给定的事件重新安排一次”,因为它不相关(但它将是事件注册的复合主键。

修改

我分享了其他人对使用ON CASCADE DELETE的担忧,但我认为这与问题并不严格相关。强制更改事件的organizerId是一项业务规则。在某些情况下,ON DELETE CASACDE是合适的,有些则不合适。

编辑2

这表明数据库的味道确实有所作为。甲骨文非常乐意将成员删除通过EVENTS和EVENTREGISTRATIONS进行级联,无需投诉。

答案 2 :(得分:1)

您确定CASCADE DELETE是个好主意吗?如果组织者被删除,事件仍然存在(考虑过去的事件),所以我认为从数据模型的角度来删除相关事件是错误的。

某些社交网络会删除某个用户过去发送给您的邮件,我觉得这些邮件非常烦人,因为它们正在删除我的数据。如果用户发送了一封电子邮件,或者就此而言,甚至是蜗牛邮件,我仍然会收到消息和用户名。

答案 3 :(得分:-2)

“数据库是SQL Server 2008,但我认为它无关紧要。”

一切都很重要。您的DBMS太瘫痪,无法为处理您的问题提供良好的支持。顺便说一下,任何SQL替代方案都是如此。

您还可以:

  1. 切换到SIRA_PRISE并使用其对任意复杂性的多个赋值和声明性数据库约束的支持。

  2. 禁用级联删除并将其替换为已触发的代码。记住不要忘记考虑级联更新。