Отношение к составному внешнему ключу в одном столбце

Я добавил столбец «версия» в таблицу, которая должна быть частью первичного ключа таблицы, но у меня есть отношения внешнего ключа к таблицам, которые не содержат версию. (И не должен) Я уверен, что получу хотя бы один ответ, объясняющий, почему это невозможно, я понимаю, почему я не могу создать отношения здесь. Я ищу элегантный/безболезненный способ обойти это. Поведение, которое мне нужно, заключается в том, что основная таблица может добавлять версии, в то время как «другая таблица» остается связанной со всеми из них. Фактически это отношение «многие ко многим» без таблицы соединений. (Однако на практике только одна «версия» основной таблицы для данного ключа активна в любой момент времени.) Я планирую обеспечить свою собственную ссылочную целостность, используя сочетание проверочных ограничений и триггеров... но есть ли лучший способ ? Спасибо

ТАБЛИЦА

TableID (uniqueidentifier) - PRIMARY KEY
Version (int) - PRIMARY KEY
...

ДРУГОЕ

OtherTableID (int) - PRIMARY KEY
TableID (uniqueidentifier)
...

person Paul    schedule 20.02.2012    source источник
comment
Если вам не нужен Version в других таблицах, не делайте его частью первичного ключа родительской таблицы.   -  person ypercubeᵀᴹ    schedule 20.02.2012
comment
Тогда у меня будет дубликат TableIDs в основной таблице...   -  person Paul    schedule 20.02.2012
comment
Должны ли другие таблицы иметь FK для конкретной версии?   -  person ypercubeᵀᴹ    schedule 20.02.2012
comment
Нет, версия не имеет значения для отношений с другими таблицами.   -  person Paul    schedule 20.02.2012


Ответы (4)


Я думаю, что было бы лучше разделить TABLE на две таблицы: одну с данными, которые никогда не меняются (это может быть просто сам идентификатор), и одну с данными, которые необходимо версионировать. OTHERTABLE будет иметь внешний ключ к первому.

(Должен упомянуть, что мы использовали этот подход там, где я работаю, и иногда он вызывал досадные сложности, особенно когда мы хотели изменить свое мнение о том, какие поля должны быть версионными. Это действительно не идеально. Но другие подходы, как правило, привести к еще большим проблемам.)

person ruakh    schedule 20.02.2012
comment
+1 - Теперь, когда я думаю об этом, я использую этот подход и в другом приложении. В этом случае это в основном просто таблица ссылок... Я посмотрю, будет ли это иметь какие-либо другие последствия для этой конкретной БД. - person Paul; 20.02.2012
comment
Реализовано, работает прекрасно. Требуется только одна строка кода, добавленная в приложение для обработки вставок в основную таблицу. - person Paul; 21.02.2012

Если я правильно понял ваши характеристики:

Parent
======
ParentID (uniqueidentifier) - PRIMARY KEY
...


OtherTable
==========
OtherTableID (int) - PRIMARY KEY
ParentID (int) -  FOREIGN KEY
...

ParentVersion
=============
ParentID (int) - PRIMARY KEY FOREIGN KEY
Version (int) - PRIMARY KEY

И если вам нужна активная версия для каждого родителя, еще одна таблица:

ParentActiveVersion
=============
ParentID (int) - PRIMARY KEY 
Version (int) 
FOREIGN KEY (ParentID, Version)
  REFERENCES ParentVersion(ParentID, Version)
person ypercubeᵀᴹ    schedule 20.02.2012

Отказ от ответственности. Следующее действительно для SQL Server. Я не претендую на другие СУБД.

Не делайте это частью PK, просто добавьте UNIQUE INDEX к этим двум полям, чтобы обеспечить уникальность:

CREATE UNIQUE INDEX ix_MyIndexName ON TABLE(TableID, Version)

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

Если в будущем вы решите, что хотите ссылаться на оба этих поля одновременно (и вы используете SQL Server), вы можете использовать уникальный индекс в качестве цели для внешнего ключа, если это необходимо.

person JNK    schedule 20.02.2012

Немного глупо, но что-то здесь будет - на основе комментария @ypercube - не могут ли другие таблицы быть построены для ссылки на версию 1 (с использованием вычисляемого столбца, чтобы заставить 1 появиться в столбце в каждой из этих таблиц)

person Damien_The_Unbeliever    schedule 20.02.2012