У меня такая структура:
- У каждого человека есть конкретная территория
- У каждого проекта есть конкретная сфера, и у каждого проекта есть конкретный человек.
- Все поля не допускают значения NULL (одно и только одно отношение)
Стандартная «живая» ситуация, бизнес-логика правильная. БД тоже правильная и работает нормально. Но когда я добавляю каскадное удаление для каждого из этих отношений, я, конечно, получаю сообщение об ошибке:
'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, должен быть удален, а затем все проекты, которые удалили людей, должны быть удалены ... Как решить эту проблему проблема? Я попытался добавить еще одну таблицу с именем ProjectAreas:
Но это не решает проблемы. Кроме того, не имея четкого представления о том, что у Project одна-единственная область.
Второй вопрос - действительно ли нужно решать эту проблему? Может быть, схемы с 3 таблицами хватит и проблему с удалением надо решать на уровне приложения?
1 ответ
Эта структура базы данных может быть нестандартной. Работа с этим, хотя и не связана напрямую с каскадным удалением, может решить вашу проблему.
Обратите внимание, что проект содержит внешние ключи как для человека, так и для области, в то время как у человека есть сама область. Теперь вопрос в том, должен ли Project быть связан с Area данного человека или нет.
Если он должен быть таким же, как у человека , то структура ненормализована - информация об одной и той же области содержится в записи Человека и Проекта; иногда это может быть сделано намеренно в целях оптимизации, но я сомневаюсь, что это так для такой маленькой базы данных. Затем вы можете удалить поле AreaID из проекта, не нужно даже рассматривать прямое каскадное удаление между ними, а вместо этого иметь его так, чтобы после удаления области удалялись и ее люди, и их проекты.
Если это может быть другая область, не имеющая отношения к человеку , тогда поле AreaID действительно необходимо; это создаст два пути удаления:
- Область >> Человек, связанный с Областью >> Проект, связанный с Человеком
- Область >> Проект, связанный с областью
Итак, SQL-серверу не нравится, когда существует несколько путей каскадного удаления (вероятно, по веским концептуальным или техническим причинам, которые я сейчас не могу назвать), поэтому вам нужно подумать, какое каскадное удаление вы предпочитаете (и выберите ON DELETE НЕТ ДЕЙСТВИЙ по отношению к другим). Есть три возможности, которые предпочтительнее решать вам:
- Область может быть удалена только в том случае, если ни один из проектов не связан с ней напрямую; однако вы по-прежнему можете удалить всех людей области вместе с их собственными проектами
- Область может быть удалена только тогда, когда люди не имеют с ней прямого отношения; однако, если с областью связаны только проекты, они удаляются вместе с областью.
- Область может быть удалена только тогда, когда с ней не связаны люди или проекты, точка; вы должны сначала удалить всех связанных людей и проекты
Надеюсь, это проясняет вам ситуацию. ^^
См. Также: Введение ограничения FOREIGN KEY может вызвать циклы или несколько каскадных путей
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.