Връзка със съставен външен ключ в една колона

Добавих колона „версия“ към таблица, която трябва да бъде част от първичния ключ на таблицата, но имам връзки на външен ключ към таблици, които не съдържат версията. (И не трябва) Сигурен съм, че ще получа поне един отговор, обясняващ защо това не е възможно, разбирам защо не мога да създам връзка тук. Търся елегантен/безболезнен начин да го заобиколя. Поведението, от което се нуждая, е основната таблица да може да добавя версии, докато „другата таблица“ остава свързана с всички тях. Това на практика е връзка много към много без таблица за свързване. (Въпреки това на практика само една „версия“ на основната таблица за даден ключ е активна във всеки даден момент.) Планирам да наложа собствената си референтна цялост, използвайки комбинация от ограничения за проверка и тригери...но има ли по-добър начин ? Благодаря

ТАБЛИЦА

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. Нямам претенции за други RDBMS.

Не го правете част от 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