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”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束

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

  • 介绍第四个(关联)表“组织者:成员ID->EventId”
  • 对其中一个依赖项禁用级联删除,并在删除操作之前以编程方式执行检查 我正在寻找关于上述内容的建议或反馈。如需更多解释/意见,敬请谅解

    注意:DB是SQLServer2008,但我认为这不重要


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

    我猜这不是一个循环依赖关系,而是一个“多级联路径”问题(不记得确切的错误消息)

    我更喜欢的解决方案是删除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,但这不重要,我想