循环或多级联删除
Cycles or multiple cascade deleting
我有以下结构:
- 每个人都有具体的面积
- 每个项目都有具体的区域,每个项目都有具体的人。
- 所有字段都不可为空(只有一种关系)
标准"live"情况,业务逻辑正确。 DB 也是正确的并且工作正常。但是,当我为这些关系中的每一个添加级联删除时,我当然会收到错误消息:
'Persons' table
- Unable to create relationship 'FK_Persons_Areas'.
Introducing FOREIGN KEY constraint 'FK_Persons_Areas' on table 'Persons' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
我明白为什么会这样(级联删除)。例如,如果删除 Area,则应删除具有该 AreaID 的所有项目,应删除具有该 AreaID 的每个人,然后应删除所有删除人员的项目...
如何解决这个问题呢?我尝试再添加一个 table 名为 ProjectAreas:
但这并不能解决问题。另外,没有清楚地了解项目只有一个区域。
第二个问题——真的有必要解决这个问题吗?也许具有 3 tables 的架构就足够了,删除问题应该在应用程序级别解决?
该数据库结构可能未规范化。处理这个问题虽然与级联删除没有直接关系,但可能会解决您的问题。
请注意,project 包含 Person 和 Area 的外键,而 person 本身有 Area。现在的问题是项目是否必须与给定人员的区域相关联。
如果一定要和person的一样,那么结构是非规范化的——Person和Project记录中包含了相同区域的信息;有时它可能是为了优化目的而故意的,但我怀疑对于这么小的数据库来说情况是否如此。然后你可以自由地从项目中删除 AreaID 字段,甚至不需要考虑直接级联删除,而是拥有它,这样一旦删除区域,它的人和他们的项目也会被删除。
如果可能是与此人无关的其他区域,那么AreaID字段确实是必须的;这将创建两个删除路径:
- 区域>>与区域关联的人>>与人关联的项目
- 地区>>与地区相关的项目
现在,SQL 服务器不喜欢有多个级联删除路径(可能出于良好的概念或技术原因,我目前无法完全命名),因此您需要考虑哪个您喜欢的级联删除(并对其他选择 ON DELETE NO ACTION)。共有三种可能,哪个更可取,由您决定:
- 只有没有项目直接关联的区域才能删除;但是,您仍然可以删除所有区域的人以及他们自己的项目
- 只有没有人直接关联的区域才能删除;但是,如果只有项目与该区域关联,它们将与该区域一起删除
- 只有当没有人或项目与之关联时,才能删除区域,期间;你必须先删除所有相关的人和项目
希望这能为您解决问题。 ^^
另请参阅:Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths
我有以下结构:
- 每个人都有具体的面积
- 每个项目都有具体的区域,每个项目都有具体的人。
- 所有字段都不可为空(只有一种关系)
标准"live"情况,业务逻辑正确。 DB 也是正确的并且工作正常。但是,当我为这些关系中的每一个添加级联删除时,我当然会收到错误消息:
'Persons' table
- Unable to create relationship 'FK_Persons_Areas'.
Introducing FOREIGN KEY constraint 'FK_Persons_Areas' on table 'Persons' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
我明白为什么会这样(级联删除)。例如,如果删除 Area,则应删除具有该 AreaID 的所有项目,应删除具有该 AreaID 的每个人,然后应删除所有删除人员的项目... 如何解决这个问题呢?我尝试再添加一个 table 名为 ProjectAreas:
但这并不能解决问题。另外,没有清楚地了解项目只有一个区域。
第二个问题——真的有必要解决这个问题吗?也许具有 3 tables 的架构就足够了,删除问题应该在应用程序级别解决?
该数据库结构可能未规范化。处理这个问题虽然与级联删除没有直接关系,但可能会解决您的问题。
请注意,project 包含 Person 和 Area 的外键,而 person 本身有 Area。现在的问题是项目是否必须与给定人员的区域相关联。
如果一定要和person的一样,那么结构是非规范化的——Person和Project记录中包含了相同区域的信息;有时它可能是为了优化目的而故意的,但我怀疑对于这么小的数据库来说情况是否如此。然后你可以自由地从项目中删除 AreaID 字段,甚至不需要考虑直接级联删除,而是拥有它,这样一旦删除区域,它的人和他们的项目也会被删除。
如果可能是与此人无关的其他区域,那么AreaID字段确实是必须的;这将创建两个删除路径:
- 区域>>与区域关联的人>>与人关联的项目
- 地区>>与地区相关的项目
现在,SQL 服务器不喜欢有多个级联删除路径(可能出于良好的概念或技术原因,我目前无法完全命名),因此您需要考虑哪个您喜欢的级联删除(并对其他选择 ON DELETE NO ACTION)。共有三种可能,哪个更可取,由您决定:
- 只有没有项目直接关联的区域才能删除;但是,您仍然可以删除所有区域的人以及他们自己的项目
- 只有没有人直接关联的区域才能删除;但是,如果只有项目与该区域关联,它们将与该区域一起删除
- 只有当没有人或项目与之关联时,才能删除区域,期间;你必须先删除所有相关的人和项目
希望这能为您解决问题。 ^^
另请参阅:Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths