Сценарий реляционного дизайна: ограничить отношения детей
Пожалуйста, рассмотрите следующий сценарий. У владельца домашнего животного может быть несколько кошек, а также может быть несколько собак. Некоторые собаки связаны (то есть они дерутся:-)) с некоторыми из кошек того же владельца.
Следующий реляционный дизайн не накладывает этого ограничения, так как кошки и собаки разных владельцев могут быть связаны. Есть ли способ наложить это ограничение с помощью реляционного дизайна?
1 ответ
Вам нужно будет использовать идентифицирующие отношения для переноса ПК владельца вниз по обеим "сторонам" и до "низа" ромбовидной зависимости:
поскольку CatDog.OwnerId
это только одно поле, оно не может идентифицировать нескольких владельцев в ряду, и, поскольку это FK для обоих видов животных, этот один владелец должен совпадать с владельцем кошки и собаки.
Другими словами, кошка может относиться только к собаке того же владельца.
Как видите, кошки и собаки идентифицируются не так, как вы, вероятно, ожидали. Кошка идентифицируется ее владельцем и отличается от других кошек того же владельца своей CatNo
, То же самое для собак.
Если вам нужен "более простой" ключ, вы всегда можете просто добавить суррогатный ключ, или, в качестве альтернативы, вы можете полностью исключить CatNo
а также DogNo
"злоупотребляя" УНИКАЛЬНЫМИ ограничениями исключительно для целей миграции OwnerId
:
(The U1
обозначает УНИКАЛЬНЫЕ ограничения.)
Теперь вы можете идентифицировать животных более кратко, но есть и обратная сторона: ограничение UNIQUE полностью избыточно с точки зрения обеспечения уникальности. Это супер-набор PK, и PK прекрасно реализует уникальность. Единственная цель УНИКАЛЬНОГО ограничения - включить CatDog.OwnerId
ссылаться на Cat.OwnerId
(а также Dog.OwnerId
) - большинство СУБД требуют, чтобы родительская конечная точка внешнего ключа была ключом.
Некоторые СУБД ( Oracle) позволят вам использовать только один индекс для принудительного применения ограничений PK и UNIQUE, но большинство из них этого не сделает. Каждый дополнительный индекс ухудшает производительность вставки / обновления / удаления.