Обнуляемые внешние ключи или разные таблицы

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

У меня есть 3 таблицы SQL:

 Articles (ArticleId PK)
  |-- Chapters (ChapterId PK, ArticleId FK)
       |-- Sections (SectionId PK, ChapterId FK)
  

У меня есть четвертая таблица, Evaluations , для хранения оценок Articles Chapters или Sections :

 Evaluations (
  EvaluationId PK,
  ArticleId NULLABLE FK,
  ChapterId NULLABLE FK,
  SectionId NULLABLE FK
)
  

Если оценка предназначена для главы, я присваиваю ей значение ChapterId и оставляю ArticleId и SectionId пустой.

Должен ли я удалить эти 3 FK и использовать вместо них 3 таблицы: ArticleEvaluations , ChapterEvaluations , SectionEvaluations ?

Есть ли лучший способ сделать это?

Комментарии:

1. Как [очень] личное мнение, я склонен разделять эти объекты, только если для этого есть очень веские причины. Хранение их как единого имеет много преимуществ с точки зрения разработки и обслуживания: вам нужно иметь дело с одной таблицей, а запросы выполняются намного проще и быстрее, особенно если вам нужно получить оценки всех типов одновременно. Я бы принудил один и только один FK не равен null , используя CHECK ограничение в таблице.

2. Это был мой следующий вопрос… Убедитесь, что определен только один из этих FK … Другим вариантом было бы иметь таблицу надмножеств, из которой статьи, главы и разделы получают и связывают тесты с этой таблицей. Как вы думаете, это был бы лучший вариант?

3. Ограничение ПРОВЕРКИ может иметь вид: check (ArticleId is not null and ChapterId is null and SectionId is null or ArticleId is null and ChapterId is not null and SectionId is null or ArticleId is null and ChapterId is null and SectionId is not null) .

4. Как насчет структуры articleId, ChapterId и SectionID ? Возможно ли, что все эти идентификаторы имеют схожую структуру (пример: все ЦЕЛОЧИСЛЕННЫЕ)?

5. @schlebe Что произойдет, если вы добавите ссылку на тип 'A' с ArticleId помощью of -42 , но такой статьи нет? Ссылка на внешний ключ предотвращает ссылку на значение, которое не существует. Что делать, если оценка ссылается на существующую статью, например 42 , и статья удаляется? Ссылка на внешний ключ предотвращает удаление строк, на которые есть ссылки. Предлагаете ли вы реализовать эту функциональность с двумя столбцами и без check ограничений? Возможно, с помощью триггеров?

Ответ №1:

Много способов,

Создайте другую таблицу EvaluationObjectType и используйте ее PK для таблицы оценки.

 EvaluationID
EvaluationObjectTypeID (it can be the of one of the three type)
EvaluationObjectID ( chapterid/articleid/sectionid) 
  

при этом вы не сможете явно создать FK для главы / статьи / раздела.

Вы должны завершить анализ дизайна, учитывая его использование в запросах, таких как отчеты и вычисления.

Другой вариант — создать одну объединенную таблицу для главы, статьи и разделов. Не видя данных, я не могу этого посоветовать.

Комментарии:

1. Я думаю, что отказ от использования FK может создать некоторые проблемы… Я рассматриваю другой вариант, который вы предлагаете. Наличие «базовой» таблицы для глав, статей и разделов. Тогда каждая из этих таблиц будет иметь идентификатор, который будет как PH, так и FK для базовой таблицы, создавая взаимно однозначное отношение. Единственная проблема, которую я вижу, заключается в том, что теперь идентификаторы в статьях, главах и разделах не будут последовательными, поскольку они являются общими для всех. Не может существовать главы с идентификатором 1 и статьи с идентификатором 1 … Не могу предсказать, будет ли это проблемой.

2. Я предпочитаю вариант 1, если вы можете обеспечить целостность данных другими способами..

3. Почему невозможно иметь главу с идентификатором 1 и статью с идентификатором 1 ? 2 идентификатора являются целыми числами, но они не связаны. У них должны быть свои личные параметры поля AUTO_INCREMENT. Можете ли вы дать дополнительные пояснения о том, как вы определяете эти идентификаторы?