Внешний ключ, относящийся к первичным ключам в нескольких таблицах?
У меня есть две таблицы, а именно 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, поэтому вам нужно убедиться, что ваше приложение правильно управляет этим ограничением (что делает его более громоздким, если у вас несколько разных приложений/служб, попавших в одну и ту же базу данных).