Как обрабатывать связь «ИЛИ» в дизайне ERD (таблицы)?
-
21-09-2019 - |
Вопрос
Я проектирую небольшую базу данных для личного проекта и одну из таблиц, назовите ее таблицей. C
, должен иметь внешний ключ к одной из двух таблиц, позвоните им A
и B
, различающиеся по записи.Каков наилучший способ реализовать это?
Идеи на данный момент:
- Создайте таблицу с двумя полями внешнего ключа, допускающими значение NULL, и подключитесь к двум таблицам.
- Возможно, с триггером для отклонения вставок и обновлений, в результате чего 0 или 2 из них будут равны нулю.
- Две отдельные таблицы с идентичными данными
- Это нарушает правило дублирования данных.
Какой более элегантный способ решить эту проблему?
Решение
Вы описываете дизайн под названием «Полиморфные ассоциации».Это часто доставляет людям неприятности.
Что я обычно рекомендую:
A --> D <-- B
^
|
C
В этом проекте вы создаете общую родительскую таблицу. D
что оба A
и B
ссылка.Это аналог обычного супертипа в объектно-ориентированном дизайне.Теперь ваш дочерний стол C
можете ссылаться на супертаблицу и оттуда перейти к соответствующей подтаблице.
С помощью ограничений и составных ключей вы можете убедиться, что данная строка D
на него можно ссылаться только A
или B
но не оба.
Другие советы
Если ты уверен, что C
будет ссылаться только на одну из двух таблиц (а не на одну из N), тогда ваш первый выбор — разумный подход (и именно тот, который я использовал раньше).Но если вы считаете, что количество столбцов внешнего ключа будет продолжать увеличиваться, это означает, что существует некоторое сходство или совпадение, которые можно включить, и вы, возможно, захотите пересмотреть свое решение.