Как реализовать полиморфные ассоциации в существующей базе данных - PullRequest
13 голосов
/ 17 января 2012

Полиморфная ассоциация (PA) довольно трудна для относительно простого требования к базе данных: пусть разные таблицы имеют дочерние записи в одной общей таблице. Классическим примером является отдельная таблица с записями комментариев, которые применяются к различным необязательно родственным объектам.

В этот вопрос Марк проделал отличную работу, показав три общих подхода к реализации PA. Я хочу использовать подход базовой таблицы, который описан более подробно в столь же превосходном ответе Билла Карвина .

Конкретный пример будет выглядеть так:

enter image description here

Первичные ключи сущностей ссылаются на идентичные значения ключей в базовой таблице, а таблица комментариев ссылается на базовую таблицу, поэтому соблюдается ссылочная целостность. Важнейшей частью здесь является то, что первичные ключи таблиц сущностей имеют отдельных доменов. Они создаются путем создания новой записи в базовой таблице и копирования ее сгенерированного ключа в первичный ключ объекта.

Теперь мой вопрос: что, если я хочу представить PA со ссылочной целостностью в существующей базе данных, имеющей сущности, которые генерируют свои собственные, взаимно перекрывающиеся первичные ключи?

Пока я вижу два варианта:

Вариант 1:

Option 1

Каждый объект сохраняет свой первичный ключ, но также получает альтернативный ключ.

Как:

  • Близко к рекомендованному подходу.
  • Базовый стол стабилен.

Неприязнь:

  • Существующие объекты должны быть изменены.
  • Трудно найти владелец комментария.

Вариант 2:

Option 2

У каждой сущности есть собственный столбец внешнего ключа в базовой таблице. Это похоже на многостолбцовый подход Марка.

Как:

  • Существующие объекты не затрагиваются.
  • Легко найти владелец комментария.

Неприязнь:

  • Разреженные столбцы
  • Базовая таблица нестабильна: нуждается в модификации, когда вводится новый объект с PA

Я опираюсь на вариант 1, возможно, с полем «EntityName» в Базовой таблице для двунаправленного поиска. Какой вариант будет лучше. Или другой, даже лучше, подход?

1 Ответ

10 голосов
/ 26 февраля 2012

Вы можете использовать вариант 1, но без дополнительного суррогатного альтернативного ключа.

Вместо этого расширите существующий первичный ключ (каждой сущности) с помощью столбца EntityType (скажем, CHAR(1), который будет E для событий, P для лиц, D дляПродукты).

Соединение (EntityId, EntityType) станет первичным ключом таблицы Entity и соответствующих соединений в трех других таблицах подтипов.

(EntityType - это простовспомогательная, справочная таблица, с 3 строками):

Polymorphic_Associations

...