2013-04-10 4 views
6

У меня есть следующие схемы баз данных:SQL Server внешний ключ для нескольких таблиц

members_company1(id, name, ...); 
members_company2(id, name, ...); 
profiles(memberid, membertypeid, ...); 
membertypes(id, name, ...) 
[ 
     { id : 1, name : 'company1', ... }, 
     { id : 2, name : 'company2', ... } 
]; 

Таким образом, каждый профиль принадлежит к определенному члену либо из company1 или Общества2 в зависимости от membertypeid значения

members_company1  —————————  members_company2  
————————————————     ———————————————— 
id  ——————————> memberid <———————————   id 
name    membertypeid     name 
         /|\ 
         | 
         | 
     profiles   | 
     ——————————  | 
     memberid ————————+ 
     membertypeid 

Я интересно, можно ли создать внешний ключ в таблице profiles для ссылочной целостности на основе memberid и membertypeid пары для ссылки на members_company1 или members_company2 записи таблицы?

+2

Похоже, вам нужно иметь company_id в таблице участников вместо того, чтобы держать таблицу участников для каждой компании. –

+0

@KevinCrowell Я знаю, хорошо, но я работаю над тем, что у меня есть, поэтому предположим, что я не контролирую таблицы 'members_company1' и' members_company2'. Единственное уродливое решение, которое я имею в виду сейчас, - создать таблицу 'members', которая будет хранить идентификаторы и типы из этих 2 таблиц, но это как бы дублирует данные и потребует больше действий при вставке новых записей в таблицы members_company. –

+3

Внешний ключ может ссылаться только на одну таблицу. Но если вы хотите начать очистку, вы можете создать таблицу 'members', как предложил @KevinCrowell, заполнить ее из двух таблиц' members_company' и заменить их на представления. Вы можете использовать триггеры «INSTEAD OF» в представлениях для «перенаправления» обновлений в новую таблицу. Это по-прежнему некоторая работа, но это был бы один из способов исправить вашу модель данных, не нарушая существующие приложения (если это возможно в вашей ситуации, конечно). – Pondlife

ответ

4

Внешний ключ может ссылаться только одну таблицу, как указано в documentation (курсив мой):

Внешний ключ (FK) представляет собой столбец или комбинация столбцов, которая используется для установления и обеспечения связи между данными в столов.

Но если вы хотите, чтобы начать очистку вещи можно создать members таблицу, как предложено @KevinCrowell, заполнить его из двух members_company таблиц и заменить их видом. Вы можете использовать триггеры INSTEAD OF для просмотра, чтобы перенаправить обновления в новую таблицу. Это по-прежнему некоторая работа, но это будет один из способов исправить вашу модель данных, не нарушая существующие приложения (если это возможно в вашей ситуации, конечно)

1

Действуя под тем, что вы не можете изменить структуру таблицы:

Вариант 1

Насколько важна ссылочной целостности для вас? Вы только делаете внутренние соединения между этими таблицами? Если вам не нужно слишком беспокоиться об этом, тогда не беспокойтесь об этом.

Вариант 2

Хорошо, вы, вероятно, придется сделать что-то об этом. Возможно, у вас есть только внутренние соединения, но вам приходится иметь дело с данными в профилях, которые не связаны ни с чем в таблицах участников. Не могли бы вы создать задание, которое выполняется один раз в день или неделю, чтобы очистить его?

Вариант 3

Да, что один может не работать. Вы можете создать триггер в таблице профилей, который проверяет ссылку на таблицы участников. Это далеко не идеально, но это гарантирует мгновенные проверки.

Мое мнение

Я бы с вариантом 2. Вы, очевидно, имеем дело с менее чем идеальной схеме. Зачем делать это хуже, чем должно быть. Пусть плохие данные сидят в течение недели; очищайте стол каждые выходные.

0

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

Добавьте две колонки под названием member_company1_id и member_company2_id к вашему profiles таблицы и создать два внешних ключей двух таблиц и позволяют nulls. Затем вы можете добавить ограничение, чтобы 1 из столбцов null, а другой - не всегда.

+0

Нужно также убедиться, что значение в member_companyX_id соответствует значению в id. Но это может сработать. – Paparazzi

+1

@Blam Это устраивает ограничение внешнего ключа. – jurgenreza

0

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

1

Да, вы можете создать таблицу, но вы не можете изменить members_company1 или members_company2?

Ваша идея создания таблицы элементов потребует больше действий при вставке новых записей в таблицы members_company.
Итак, вы можете создавать триггеры для members_company1 и members_company2 - это не изменяется?

Каковы ограничения на то, что вы можете сделать?

Если вам просто нужна совместимость при выборе для members_company1 и members_company2, тогда создайте таблицу реальных членов и создайте представления для members_company1 и members_company2.
Базовый выбор не знает, что это вид или таблица на другом конце.

CREATE VIEW dbo.members_company1 
AS 
SELECT id, name 
FROM members 
where companyID = 1 

Вы могли возможно даже обрабатывать вставки, обновления и удаления с вместо-о

INSTEAD OF INSERT Triggers

+0

Правильно, я не могу. Но вопрос не в триггерах и дополнительных таблицах, моя забота касалась ограничения внешнего ключа более чем на двух таблицах. –

+0

Комментарий «Единственное уродливое решение, которое я имею в виду сейчас, - создать таблицу участников, которая будет хранить идентификаторы и типы из этих двух таблиц, но это как бы дублирует данные и потребует больше действий, когда новые записи будут вставлены в таблицы members_company». Это дополнительная таблица и триггеры. Каково реальное ограничение? – Paparazzi

+0

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

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