对于一对多关系,每个级联删除选项的所有副作用是啥?
Posted
技术标签:
【中文标题】对于一对多关系,每个级联删除选项的所有副作用是啥?【英文标题】:What are all the side effects of each cascade delete option for a one-to-many relationship?对于一对多关系,每个级联删除选项的所有副作用是什么? 【发布时间】:2013-06-24 01:39:14 【问题描述】:假设我有两个表,Department 和 Employee。每个员工只有一个部门。每个部门都有一名或多名员工。
是否可以使用任何级联删除选项组合来强制执行此规则而无需编写特殊代码?
换句话说,这里有两条规则:
-
只有在没有员工时才能删除部门。
当一个部门的最后一个员工被删除时,该部门应该被删除。
如果不是,那么我应该使用哪个集合来最大程度地帮助我执行此业务逻辑?
【问题讨论】:
【参考方案1】:假设我们在每个场景运行之前的表中有以下数据:
Sales (Department)
Amy (Employee)
Bob (Employee)
场景 1:级联/无效
Employee --(Cascade)--> Department
Department --(Nullify)--> Employee
删除员工:
删除 Bob 将导致 Sales 被删除,并且 Amy 的部门为 NULL。
Amy
删除部门:
如果我们这次重新开始并删除 Sales,Amy 和 Bob 将在数据库中留下 NULL 部门。
Amy
Bob
场景 2:级联/拒绝
Employee --(Cascade)--> Department
Department --(Deny)--> Employee
删除员工:
删除 Bob 会引发异常:The operation couldn’t be completed. (Cocoa error 1600.)
。
删除部门:
如果我们这次重新开始并删除 Sales,我们会得到异常:The operation couldn’t be completed. (Cocoa error 1600.)
。
场景 3:级联/级联
Employee --(Cascade)--> Department
Department --(Cascade)--> Employee
删除员工:
删除 Bob 会导致 Sales 被删除。结果,艾米也被删除了。
(empty DB)
删除部门:
如果我们这次重新开始并删除Sales,这将导致所有员工也被删除。
(empty DB)
场景 4:无效/无效
Employee --(Nullify)--> Department
Department --(Nullify)--> Employee
删除员工:
删除 Bob 不会更改数据库的其余部分。
Sales
Amy
现在删除 Amy 将导致 Sales 没有任何员工。
Sales
删除部门:
如果我们这次重新开始并删除 Sales,这将导致 Amy 和 Bob 的部门为 NULL。
Amy
Bob
场景 5:无效/拒绝
Employee --(Nullify)--> Department
Department --(Deny)--> Employee
删除员工:
删除 Bob 不会更改数据库的其余部分。
Sales
Amy
现在删除 Amy 将导致 Sales 没有任何员工。
Sales
删除部门:
如果我们这次重新开始删除Sales,会引发异常:The operation couldn’t be completed. (Cocoa error 1600.)
。
场景 6:无效/级联
Employee --(Nullify)--> Department
Department --(Cascade)--> Employee
删除员工:
删除 Bob 不会更改数据库的其余部分。
Sales
Amy
现在删除 Amy 将导致 Sales 没有任何员工。
Sales
删除部门:
如果我们这次重新开始并删除 Sales,它将删除所有员工。
(empty DB)
场景 7:拒绝/无效
Employee --(Deny)--> Department
Department --(Nullify)--> Employee
删除员工:
删除 Bob 会引发异常:The operation couldn’t be completed. (Cocoa error 1600.)
。
删除部门:
如果我们这次重新开始并删除 Sales,这将导致 Amy 和 Bob 的部门为 NULL。
Amy
Bob
场景 8:拒绝/拒绝
Employee --(Deny)--> Department
Department --(Deny)--> Employee
删除员工:
删除 Bob 会引发异常:The operation couldn’t be completed. (Cocoa error 1600.)
。
删除部门:
如果我们这次重新开始删除Sales,会引发异常:The operation couldn’t be completed. (Cocoa error 1600.)
。
场景 9:拒绝/级联
Employee --(Deny)--> Department
Department --(Cascade)--> Employee
删除员工:
删除 Bob 会引发异常:The operation couldn’t be completed. (Cocoa error 1600.)
。
删除部门:
如果我们这次重新开始并删除Sales,它将删除所有员工。
(empty DB)
结论:
因此,似乎最好使用方案 5(取消/拒绝),您必须编写自定义代码才能在删除最后一个员工后删除部门。这种情况还可以确保您不会过早地意外删除部门。
【讨论】:
还将Department的employees关系的最小基数设置为1。它并不能代替需要特殊代码来删除空部门,但是如果你不这样做它会捕获错误。以上是关于对于一对多关系,每个级联删除选项的所有副作用是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Flask 学习-84.Flask-SQLAlchemy 一对多关系级联删除
Flask 学习-84.Flask-SQLAlchemy 一对多关系级联删除