且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

级联删除或使用触发器?

更新时间:2023-02-05 10:25:33

CASCADE DELETE 在 MSSQL Server 中只能级联到单个表.如果您有两个表与一个维度表有外键关系,则只能级联删除其中一个.(这是为了防止删除通过多条路径级联并产生冲突,就像C++允许多重继承而C#只允许单继承一样)

CASCADE DELETE in MSSQL Server can only cascade to a single table. If you have two tables with foreign key relationships to a dimension table, you can only cascade delete to one of them. (This is to prevent deletes cascading through multiple paths and creating conflicts, much as C++ allows multiple inheritance but C# only allows single inheritance)

在这种情况下,您将***使用触发器或在代码中专门处理这种情况.

When this is the case, you are forced to use triggers or specifically handle the case in your code.

出于这个原因,我看到很多人在所有情况下都选择使用触发器.即使只有一张外表.这确保了一致性,因此人们知道在维护数据库时要查找什么.

For this reason I have seen many people opt for using triggers in all cases. Even when there is only one foreign table. This ensures consistency and so people know what to look for when maintaining the database.

如果可以将删除级联到多个表,我会说这将是最可取的选择.然而,这种限制使水变得混乱,我目前更倾向于拥有所有此类行为的触发器.使用触发器进行级联删除和更新的开销仅在编码方面很小,但确实允许真正通用的标准实践.

If one could cascade a delete to more than one table I would say it would be the most preferable option. This limitation, however, muddies the waters and I'm currently more in favour of triggers owning all such behaviours. The overhead in using triggers for cascaded deletes and updates is only minor in terms of coding, but does allow for standard practices that are truely generic.

您可能想将已接受的答案"移给其他人,我已经发现我在上述内容上是错误的.

You might want to move the 'accepted answer' to someone else, I've worked out I was wrong abot the above.

您可以有多个事实表,其中包含对单个维度表的 ON DELETE CASCADE 外键约束.

You CAN have multiple fact tables have ON DELETE CASCADE Foreign Key Contraints to a signle Dimension table.

你不能做的是让一个事实表具有多个维度表的 ON DELETE CASCADE 外键约束.

What you Can't do is have one Fact Table have have ON DELETE CASCADE Foreign Key Constraints to multiple Dimension Tables.

例如……
- 维度表 [Person] (id INT IDENTITY, )
- 维度表 [考试] (id INT IDENTITY, )
- 人脸表[Exam_Score](person_id INT,exam_id INT,score INT)

So for example...
- Dimension Table [Person] (id INT IDENTITY, )
- Dimension Table [Exam] (id INT IDENTITY, )
- Face Table [Exam_Score] (person_id INT, exam_id INT, score INT)

如果 Person 或 Exam 被删除,您希望相关的 Exam_Score 记录也被删除.

If either the Person or the Exam are deleted, you'd want the associated Exam_Score record(s) to also be deleted.

这在 MS SQL Server 中使用 ON DELETE CASCADE 是不可能的,因此需要触发器.

This is not possible using ON DELETE CASCADE in MS SQL Server, thus the need for triggers.

(向 Mehrdad 道歉,他试图向我解释这一点,但我完全没有理解他的观点.)

(Apologies to Mehrdad who tried to explain this to me but I completely missed his point.)