2014-09-12 4 views
1

У меня есть много-много отношений с таблицей ссылок, и мне нужно оформить набор правил. Ниже приведена моя проблема:Составные первичные ключи и правила таблицы ссылок

Слева (L) и справа (R) (L & R) Таблица: у обоих есть составные (спасибо stakx для исправления меня) первичные ключи. Таблица ссылок имеет свой собственный первичный ключ, но, очевидно, потому что таблицы L & R имеют каждый составной праймериз, таблица ссылок должна содержать несколько внешних ключей. Нет проблем. т.е.

L Table: 
LID  (int)  PK1 
LSomeDate (DateTime) PK2 
Other Fields... 

R Table: 
RID  (int)  PK1 
RSomeDate (DateTime) PK2 
Other Fields... 

Link Table: 
ID  (int)  PK 
LID  (int)  FK1 
LSomeDate (DateTime) FK1 
RID  (int)  FK2 
RSomeDate (DateTime) FK2 

Требование 1: Сущность в любой таблице может существовать без другой. Поэтому вместо 1: M мы должны иметь 0: M по обе стороны M: M. Я предполагаю (возможно, ошибочно), что это означает, что я должен оставить внешние ссылки в таблице ссылок. Но если я это сделаю, я могу ввести LID и оставить поле LSomeDate нулевым. или наоборот. Аналогично с RID и RSomeDate.

Первый вопрос: каким стандартным способом создать какое-либо «правило (ограничение, ограничение, значение по умолчанию, триггер и т. Д.)», Что заставит пользователя ввести LID, если LSomeDate был введен или ввести LSomeDate, если Была введена LID. Затем я могу применить их к R FK. Это предотвратит упущение нулей в части FK.

По существу ... Либо вся сторона L FK имеет значение null, либо оба поля заполняются (действительный ref). Аналогично для R, но это будет отдельно.

Другой вопрос: при создании таблиц ссылок, если таблица L содержит FKID правой таблицы и наоборот, например ... Если таблица L выше также содержит RID и RSomeDate в качестве внешних ключей, и наоборот в таблице R, или тот факт, что они указаны в таблице ссылок достаточно.

Заранее благодарен.

+1

Замечание по терминологии: хотя таблица может иметь несколько ключей-кандидатов, они могут иметь только один первичный ключ. Однако этот первичный ключ может быть составным (т.е. состоять из более чем одного столбца).Предполагаю, вы хотели сказать, что обе ваши таблицы L & R имеют составной первичный ключ? – stakx

+0

@stakx - Я сделал и обновил вопрос. Благодарю. :) –

+1

Что вы подразумеваете, говоря: _ «... заставляют пользователя вводить ... ID» _? Входит ли пользователь непосредственно в базу данных? То есть, вы хотите принудительно применять это правило непосредственно на уровне базы данных или на уровне приложения? – stakx

ответ

1

Единственная причина наличия записи в таблице ссылок - связать одну запись L с другой R-записью. Если один L существует без привязки к какому-либо R, то в L есть recird, но не будет записи для этой конкретной комбинации L и R в таблице ссылок.

То есть запись в таблице ссылок N: N существует только в том случае, если связаны L и R. То есть, если две записи L и R не связаны («один существует без другого»), то просто нет записи в таблице ссылок. И поэтому в таблице ссылок даже нет необходимости в значениях NULL.

Значение, в идеале, все столбцы таблицы ссылок объявлены NOT NULL; и внезапно ваша проблема исчезнет!

(Это кстати не имеет ничего общего с вашими первичными ключами являются композитом,.. И тот же факт продержится несоставные ключи)

Если вы, несмотря на это, все еще хотел объявить эти столбцы NULL состояния , и вы хотели бы обеспечить на уровне базы данных, что, например, все L внешние ключи в таблице ссылок не частично NULL, вы могли бы добавить CHECK ограничение:

ALTER TABLE LinkTable 
ADD CONSTRAINT CK_LinkTable_LID_LSomeDate 
CHECK ((LID IS NULL  AND LSomeDate IS NULL ) 
    OR (LID IS NOT NULL AND LSomeDate IS NOT NULL)) 

Но опять же, это было бы гораздо лучше, если бы все эти внешние ключи колонок были NOT NULL состоянии, в первую очередь, потому что именно так должна быть создана таблица ссылок N: N.

+0

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

+1

@FrancisRodgers: Не беспокойтесь, приятель. Мы все здесь, чтобы учиться. (Не стесняйтесь повышать или даже принимать ответ, если вы чувствуете, что это было полезно. ;-) – stakx

+0

Итак, если я правильно понимаю. Забудьте об ограничении, просто не позволяйте FK в таблице ссылок быть нулевым. Это связано с тем, что 0: N можно представить с любой стороны, просто введя запись на соответствующей стороне и не связывая ее через таблицу ссылок. Таблица ссылок нужна только при привязке одной стороны к другой ... Правильно ли это? –

Смежные вопросы