编辑:这是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约束。
问题:
处理这个问题的好方法是什么?我有两个解决方案:
我正在寻找有关上述内容的建议或反馈。赞赏额外的解释/评论。
注意:数据库是SQL Server 2008,但我认为无关紧要。
编辑:假设删除事件 IS 所需行为(示例已简化)。
答案 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替代方案都是如此。
您还可以:
切换到SIRA_PRISE并使用其对任意复杂性的多个赋值和声明性数据库约束的支持。
禁用级联删除并将其替换为已触发的代码。记住不要忘记考虑级联更新。