【问题标题】:cascading deletes causing multiple cascade paths级联删除导致多个级联路径
【发布时间】:2011-03-23 22:46:15
【问题描述】:

我使用的是 SQlServer 2008,下面显示了一些数据表的摘录:

用户

标识(PK)

用户项目

用户 ID (PK) ItemId (PK) - (2列的复合键) ...

用户项目投票

用户 ID (PK) 项目 ID (PK) VoterId (PK) - (3 列的复合键)

我定义了以下关系:

  • User.Id -> UserItems.UserId
  • (UserItems.UserId, UserItems.ItemId) -> (UserItemVotes.UserId, UserItemVotes.ItemId)
  • UserId.Id -> UserItemVotes.VoterId

现在,我在打开级联删除时遇到了问题。添加第三个关系时,我收到错误“...可能导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他外键约束。” 我真的不想这样做,理想情况下,如果用户被删除,我想删除他们的用户项和/或他们的投票。

这是一个糟糕的设计吗?或者有没有办法从 SQL Server 获得我想要的行为?

【问题讨论】:

    标签: sql-server database-design


    【解决方案1】:

    批准的答案不是一个好的答案。所描述的场景设计不错,依赖数据库完成工作也不是“冒险”。

    最初的问题描述了一个完全有效的场景,并且设计经过深思熟虑。显然,删除用户应该删除用户的项目(以及对它们的任何投票),并删除用户对任何项目(甚至是属于其他用户的项目)的投票。当用户记录被删除时,要求数据库执行这种级联删除是合理的。

    问题是 SQL Server 无法处理它。它对级联删除的实现是有缺陷的。

    【讨论】:

      【解决方案2】:

      “UserItems.ItemId -> UserItemVotes.UserId”

      这个看起来非常可疑。

      【讨论】:

      • 我认为 DanDan 是在说 (UserItems.UserId, UserItems.ItemId) -> (UserItemVotes.UserId, UserItemVotes.ItemId)。
      【解决方案3】:

      我会导致糟糕的设计。虽然大多数 DBMS 可以管理级联删除,但使用此内置功能存在风险。您的场景是为什么这些类型的事物通常在应用程序代码中进行管理的一个完美示例。在那里,您可以准确确定需要删除的内容以及删除顺序。

      【讨论】:

      • 好的,我将在存储过程中执行此操作,而不是在这种情况下依赖父表来删除其子表。
      猜你喜欢
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 2019-07-14
      • 1970-01-01
      • 2013-12-10
      • 2016-03-26
      • 2019-09-22
      • 1970-01-01
      相关资源
      最近更新 更多