Database design DB:数据库中的循环依赖项
编辑:这是一个我起初没有找到的文件 我正在为用户组事件管理构建一个网站Database design DB:数据库中的循环依赖项,database-design,rdbms,database,Database Design,Rdbms,Database,编辑:这是一个我起初没有找到的文件 我正在为用户组事件管理构建一个网站 Members : Name, Id Events : DateTime, Topic, OrganizerId (from FK to Members table) EventRegistrations : MemberId (FK), EventId (FK) 说明(冗余): 会员可以创建和管理活动,并成为该活动的组织者。 任何成员都可以注册事件,并在EventRegistrations中创建记录 问题: 当我在表
Members : Name, Id
Events : DateTime, Topic, OrganizerId (from FK to Members table)
EventRegistrations : MemberId (FK), EventId (FK)
说明(冗余):会员可以创建和管理活动,并成为该活动的组织者。
任何成员都可以注册事件,并在EventRegistrations中创建记录 问题:
当我在表之间创建PK-FK依赖关系时,会出现一个错误,错误是: 在表“eventregistrations”上引入外键约束“reg_evt_fk”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束 问题:
处理这个问题的好方法是什么?首先,我有两个解决方案:
编辑:假设删除事件是必需的行为(示例已简化)。我猜这不是一个循环依赖关系,而是一个“多级联路径”问题(不记得确切的错误消息) 我更喜欢的解决方案是删除OrganizerId级联删除,因为删除组织成员不应自动删除成员的事件,并将此部分实现为SP
您仍然可以在INSTEAD OF DELETE触发器或SP中实现子记录删除。我想这不是一个循环依赖关系,而是一个“多级联路径”问题(不记得确切的错误消息) 我更喜欢的解决方案是删除OrganizerId级联删除,因为删除组织成员不应自动删除成员的事件,并将此部分实现为SP
您仍然可以在INSTEAD OF DELETE触发器或SP中执行子记录删除。您确定
级联删除是个好主意吗?如果正在删除组织者,事件仍然会发生(考虑过去的事件),因此从数据模型的角度来看,我认为删除关联事件是错误的
一些社交网络会删除某个用户过去发送给你的消息,我觉得这非常烦人,因为他们正在删除我的数据。如果用户发送了一封电子邮件,或者,就这一点而言,即使是普通邮件,我仍然会保留该消息和用户名。您确定级联删除是个好主意吗?如果正在删除组织者,事件仍然会发生(考虑过去的事件),因此从数据模型的角度来看,我认为删除关联事件是错误的
一些社交网络会删除某个用户过去发送给你的消息,我觉得这非常烦人,因为他们正在删除我的数据。如果用户发送了一封电子邮件,或者,就这一点而言,即使是蜗牛邮件,我仍然会保留该消息和用户名。不知道为什么会得到循环依赖关系。你确定你已经以正确的方式声明了关系吗
你的桌子
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>
注意:我没有费心去实现规则“一个成员对任何给定事件只能抵抗一次”,因为它不相关(但它将是eventregistrations上的复合主键)
编辑
我同意其他人对使用ON CASCADE DELETE的担忧,但我认为这与问题并不严格相关。强制更改事件的organizerId是一项业务规则。在某些情况下,删除CASACDE是适当的,而在某些情况下则不是
编辑2
这表明,数据库的味道毕竟会有所不同。Oracle很乐意毫无怨言地将成员的删除级联到事件和事件注册中。不知道为什么会得到循环依赖关系。您确定已使用正确的Cardinality声明了关系吗
你的桌子
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>
注意:我没有费心去实现规则“一个成员对任何给定事件只能抵抗一次”,因为它不相关(但它将是eventregistrations上的复合主键)
编辑
我同意其他人对使用ON CASCADE DELETE的担忧,但我认为这与问题并不严格相关。强制更改事件的organizerId是一项业务规则。在某些情况下,删除CASACDE是适当的,而在某些情况下则不是
编辑2
这表明,数据库的味道毕竟会有所不同。Oracle非常乐意将成员的删除级联到事件和事件注册,而不必抱怨。“DB是SQL Server 2008,但我认为这不重要。”
这一切都很重要。你的数据库管理系统太残废了,无法为处理你的问题提供适当的支持。顺便说一句,任何SQL替代方案也是如此
您还可以:
切换到SIRA_PRISE,并使用它对任意复杂度的多重赋值和声明性数据库约束的支持
禁用级联删除并将其替换为触发代码。记住不要忘记考虑级联更新
“DB是SQL Server 2008,但这不重要,我想