【问题标题】:Cascade deletes on linked table joining 2 tables that each have a cascade delete to another table. How?链接表上的级联删除连接 2 个表,每个表都有一个级联删除到另一个表。如何?
【发布时间】:2011-06-27 05:17:16
【问题描述】:

让我们假设以下对象是 SQL 中的表:

  • Companies
  • Employees(指公司)
  • Meetings(也指公司)

员工可以参加会议,所以我们有一个链接表:

  • EmployeeMeetings(即对员工和会议的 FK)

此外,我无法触摸 Companies 表(例如,对此没有触发器)。我想要的是:

  1. 如果公司被移除,所有员工都会被移除
  2. 如果公司被删除,所有会议都会被删除
  3. 如果员工或会议被删除,所有 EmployeeMeeting 记录都会被删除

不幸的是,我被困住了,因为这会引发可怕的“可能导致循环或多个级联路径”。鉴于限制,如何解决这个问题?我想我什至不能同时放入两个 FK,或者存在删除公司后无法删除员工或会议的风险,因为 EmployeeMeetings 中的 FK 会阻止这种情况。对吧?

【问题讨论】:

  • 触发器是否被完全禁止,或者您是否允许在EmployeesMeetings 上使用触发器?

标签: sql-server database-design foreign-keys cascade cascading-deletes


【解决方案1】:

如果我是你,我会完全避免触发器和级联删除。他们总是以意想不到的方式工作。

与触发器和级联删除相比,存储过程更容易理解。所以我会创建一个存储过程,在公司之前删除会议和员工:

create procedure dbo.RemoveCompany(@companyId int)
as
delete * from employees where CompanyId = @companyId
delete * from meetings where CompanyId = @companyId
delete * from companies where Id = @companyId

作为额外的好处,存储过程在您的数据库和应用程序之间创建了一个明确的合同。

【讨论】:

  • 我讨厌级联删除,因为如果出于性能原因从父表中删除一百万条记录,我会以不同的方式编写代码。或者至少,我可能会在非高峰时段运行它。我不希望有人在上午 10 点删除一些记录,这会导致数据库在接下来的四个小时内被锁定在事务中,因为它会从数百个表中删除数百万个子记录。级联删除是邪恶的,我认为绝不应该允许。
【解决方案2】:

具有从公司到员工、从公司到会议以及从员工到员工会议的级联删除。 在 EmployeeMeetings 中删除的表 Meetings 上删除后添加触发器。

create trigger Meetings_Delete on Meetings after delete
as
begin
  set nocount on;
  delete EmployeeMeetings
  from deleted
  where deleted.MeetingsID = EmployeeMeetings.MeetingsID
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2012-01-07
    • 2017-08-10
    • 1970-01-01
    • 2021-05-03
    相关资源
    最近更新 更多