简体   繁体   中英

Cycles or multiple cascade deleting

I have the following structure: 在此处输入图片说明

  • Each person has concrete area
  • Each project has concrete area and each project has concrete person.
  • All fields are not nullable (one and only one relationship)

Standard "live" situation, business-logic is correct. DB is correct too and works fine. But when I add cascade deleting for each of these relationship of course I get the error:

'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.

I understand why it happened (cascade deleting). For example, if Area is deleted, all projects, which has this AreaID, should be deleted and each persons, which has this AreaID, should be deleted and then all Projects, which have deleted persons should be deleted... How to solve this problem? I tried to add one more table named ProjectAreas:

在此处输入图片说明

but this isn't solving the problem. Also, not having clear understanding that Project has one and only one area.

Second question - is it really necessary to solve this problem? Maybe schema with 3 tables is enough and problem with deleting should be solved on application level?

That database structure might be unnormalised. Dealing with that, while not related to cascade deletion directly, might solve your problem.

Note that project contains foreign keys for both Person and Area, while person has Area themselves. Now the question is whether Project must be associated with Area of the given person or not.

If it must be the same as person's , then the structure is unnormalised - the information about same area is contained in Person and Project record; sometimes it might be intentional for optimisation purposes, but I doubt it's the case for such a small database. Then you're free to remove AreaID field from project, don't need to even consider direct cascade deletion between and instead have it so that once area is deleted, its people and their projects are deleted as well.

If it might be other area unrelated to the person , then the AreaID field is indeed necessary; that would create two deletion paths:

  • Area >> Person associated with Area >> Project associated with Person
  • Area >> Project associated with Area

Now then, SQL server doesn't like when there are multiple cascade deletion paths (probably for good conceptual or technical reasons I can't quite name at the moment), so you need to think which cascade deletion you prefer (and choose ON DELETE NO ACTION on the others). There are three possibilities, which is preferable is for you to decide:

  • Area can be deleted only when no projects have direct association with it; however, you still can delete all area's people along with their own projects
  • Area can be deleted only when no people have direct association with it; however, if only projects are associated with the area, they're deleted along with the area
  • Area can be deleted only when no people or projects are associated with it, period; you must delete all related people and projects first

Hope this clears things up for you. ^^

See also: Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM