Внешний ключ, относящийся к первичным ключам в нескольких таблицах?

У меня есть две таблицы, а именно employee_ce и employees_sn под сотрудниками базы данных.

Оба они имеют свои уникальные столбцы первичного ключа.

У меня есть другая таблица, называемая deductions, чей столбец внешнего ключа я хочу ссылаться на первичные ключи employee_ce, а также employee_sn. Возможно ли это?

например

employees_ce
--------------
empid   name
khce1   prince

employees_sn
----------------
empid   name
khsn1   princess

так это возможно?

deductions
--------------
id      name
khce1   gold
khsn1   silver

Ответ 1

Предполагая, что я правильно понял ваш сценарий, это то, что я бы назвал правильным способом для этого:

Начните с описания вашей базы данных более высокого уровня! У вас есть сотрудники, а сотрудники могут быть "ce" сотрудниками и "sn" сотрудниками (независимо от того, что есть). В объектно-ориентированных терминах существует класс "сотрудник" с двумя подклассами "ce employee" и "sn employee".

Затем вы переводите это описание более высокого уровня в три таблицы: employees, employees_ce и employees_sn:

  • employees(id, name)
  • employees_ce(id, ce-specific stuff)
  • employees_sn(id, sn-specific stuff)

Поскольку все сотрудники являются сотрудниками (duh!), каждый сотрудник будет иметь строку в таблице employees. Сотрудники "ce" также имеют строку в таблице employees_ce, а сотрудники "sn" также имеют строку в таблице employees_sn. employees_ce.id является внешним ключом для employees.id, так же как employees_sn.id.

Чтобы обратиться к сотруднику любого вида (ce или sn), обратитесь к таблице employees. То есть, у внешнего ключа, с которым у вас возникли проблемы, следует обратиться к этой таблице!

Ответ 2

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

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

                 employee       
employees_ce     ————————       employees_sn
————————————     type           ————————————
empid —————————> empid <——————— empid
name               /|\          name
                    |  
                    |  
      deductions    |  
      ——————————    |  
      empid ————————+  
      name

type в таблице employee будет ce или sn.

Ответ 3

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

Решение 1:

  • Добавьте поле tinyint в employee_ce и employee_sn, значение по умолчанию которого отличается в каждой таблице (это поле представляет собой "идентификатор таблицы", поэтому мы будем называть их tid_ce и tid_sn)

  • Создайте уникальный индекс в каждой таблице, используя таблицу PK и поле идентификатора таблицы.

  • Добавьте поле tinyint в таблицу "Deductions", чтобы сохранить вторую половину внешнего ключа (идентификатор таблицы)

  • Создайте 2 внешних ключа в таблице "Вычеты" (вы не можете принудительно применять ссылочную целостность, потому что либо один ключ будет действителен, либо другой... но никогда не будет:

    ALTER TABLE [dbo].[Deductions]  WITH NOCHECK ADD  CONSTRAINT [FK_Deductions_employees_ce] FOREIGN KEY([id], [fk_tid])
    REFERENCES [dbo].[employees_ce] ([empid], [tid])
    NOT FOR REPLICATION 
    GO
    ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_ce]
    GO
    ALTER TABLE [dbo].[Deductions]  WITH NOCHECK ADD  CONSTRAINT [FK_Deductions_employees_sn] FOREIGN KEY([id], [fk_tid])
    REFERENCES [dbo].[employees_sn] ([empid], [tid])
    NOT FOR REPLICATION 
    GO
    ALTER TABLE [dbo].[Deductions] NOCHECK CONSTRAINT [FK_600_WorkComments_employees_sn]
    GO
    
    employees_ce
    --------------
    empid    name     tid
    khce1   prince    1
    
    employees_sn
    ----------------
    empid    name     tid 
    khsn1   princess  2
    
    deductions
    ----------------------
    id      tid       name  
    khce1   1         gold
    khsn1   2         silver         
    ** id + tid creates a unique index **
    

Решение 2: Это решение позволяет поддерживать ссылочную целостность: 1. Создайте второе поле внешнего ключа в таблице "Deductions", допустите значения Null в обоих внешних ключах и создайте нормальные внешние ключи:

    employees_ce
    --------------
    empid   name
    khce1   prince 

    employees_sn
    ----------------
    empid   name     
    khsn1   princess 

    deductions
    ----------------------
    idce    idsn      name  
    khce1   *NULL*    gold
    *NULL*  khsn1     silver         

Целостность проверяется только в том случае, если столбец не равен нулю, поэтому вы можете поддерживать ссылочную целостность.

Ответ 4

Я знаю, что это длинная застойная тема, но в случае, если кто-то ищет здесь, так это то, как я занимаюсь внешними ключами нескольких таблиц. С помощью этой техники у вас нет каких-либо принудительных каскадных операций DBA, поэтому, пожалуйста, убедитесь, что вы имеете дело с DELETE и т.д. В вашем коде.

Table 1 Fruit
pk_fruitid, name
1, apple
2, pear

Table 2 Meat
Pk_meatid, name
1, beef
2, chicken

Table 3 Entity's
PK_entityid, anme
1, fruit
2, meat
3, desert

Table 4 Basket (Table using fk_s)
PK_basketid, fk_entityid, pseudo_entityrow
1, 2, 2 (Chicken - entity denotes meat table, pseudokey denotes row in indictaed table)
2, 1, 1 (Apple)
3, 1, 2 (pear)
4, 3, 1 (cheesecake)

SO Op Пример будет выглядеть следующим образом

deductions
--------------
type    id      name
1      khce1   gold
2      khsn1   silver

types
---------------------
1 employees_ce
2 employees_sn

Ответ 5

Технически возможно. Вероятно, вы бы указали employee_ce на вычеты и employee_sn. Но почему бы вам не объединить employee_sn и employees_ce? Я не вижу причин, почему у вас есть две таблицы. От одного до многих отношений. И (не в этом примере) много столбцов.

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

Ответ 6

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

Ответ 7

Предполагая, что по какой-то причине у вас должно быть две таблицы для двух типов сотрудников, я продолжу ответ на vmarquez:

Схема:

employees_ce (id, name)
employees_sn (id, name)
deductions (id, parentId, parentType, name)

Данные в выводах:

deductions table
id      parentId      parentType      name
1       1             ce              gold
2       1             sn              silver
3       2             sn              wood
...

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