2

Так что эти две таблицы в моей базе данных:Создание отношения один-к-одному между таблицами с существующей один-к-многим

Companies 
-------------------- 
CompanyID (PK) 
Name 


Employees 
-------------------- 
EmployeeID (PK) 
CompanyID (FK) 
Name 

В принципе, одна компания имеет много сотрудников.

Но я бы хотел, чтобы каждая компания имела ровно одного сотрудника, который является основным контактом. Моя первоначальная мысль состояла в том, чтобы просто добавить поле MainContactID в таблицу Companies, которая ссылается на EmployeeID в Employees, но это создаст цикл с отношениями.

Каков наилучший способ для этого?

ответ

2

Нет ничего (на мой взгляд) неправильно с вашей первоначальной мыслью.

Хотя есть петля, как вы выразились, здесь нет никакой проблемы.

Наличие companies.MainContactEmployeeID гарантирует, что существует только один такой контакт для каждой компании.

Затем добавить внешний ключ Companies(CompanyID,MainContactEmployeeID): Employees(CompanyID,EmployeeID) гарантирует, что работник фактически работает в этой компании. (Требуется также уникальный уникальный индекс в таблице Employee).

Такой внешний ключ возможен только из-за «петли». Это, конечно, не проблема.

+0

Это создаст ситуацию с круговой ссылкой, сотрудники уже являются дочерней компанией Компании, она также не может быть родительской или вы не сможете вставлять записи. – HLGEM

+2

@HLGEM - Я не согласен, это образец, который я использовал, и он работает. '1.' Создайте компанию без MainContact (NULL FK). '2.' Создайте дочерних сотрудников в этой компании. '3. 'Обновите основной контакт компании с одним из созданных вами сотрудников. – MatBailie

0

Создание таблицы с помощью комбинированного первичного ключа, например:

Company_MainContact 
-------------------- 
EmployeeID (PK) (FK-->Employee) 
CompanyID (PK) (FK-->Company) 
+0

Хотя это действительно работает и имеет свои достоинства, я думаю, что OP заинтересован в * почему * так же, как предлагаемые варианты. У вас есть причины, почему вы делаете это так, когда всегда 1: 1? – MatBailie

+0

Исходя из предположения, что база данных уже заполнена, а «рабочий» и этот основной идентификатор контакта были новым требованием, это, скорее всего, самое быстрое и простое решение, не требующее 1) рефакторинга модели данных или 2) уродливых хаков, связанных к триггерам и т. д. – Chad

+0

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

1

я лично предпочитаю эту модель:

Organization 
------------- 
organization_id 
name 
other_columns 

Person 
------------- 
person_id 
name 
other_columns 

Person_Organization 
-------------------- 
person_id 
organization_id 
begin_date 
end_date 
relationship_cd 

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

+0

Как бы вы обеспечили соблюдение «Максимального 1 сотрудника для основного контакта»? – MatBailie

+1

Может существовать несколько способов: вы можете использовать ограничение или триггер insert/update для Person_Organization для принудительного применения «Max 1 Employee». Я думаю, что это значительно расширилось, чтобы обеспечить соблюдение этого таким образом, а не испечь его непосредственно в структуре таблицы. –

2

Мы делаем что-то similar с адресами и электронными письмами и телефонами. У нас есть поле, которое отмечает запись как основную. Затем это поле поддерживается с помощью триггера, так что, если основная точка контакта изменяется, у вас все еще есть только одно, и если основной контакт удален, триггер использует бизнес-правила, чтобы выяснить, какая оставшаяся запись получит флаг, поскольку мы должны иметь хотя бы одну основную запись, если у нас вообще есть записи.

1

Если вы не хотите иметь

  • круговые траектории в отношениях ФК
  • NULLS в колонках FK

вы можете использовать это:

Добавить UNIQUE ограничение в Employee(CompanyID, EmployeeID) и составить другую таблицу:

Company_MainContact 
-------------------- 
CompanyID (PK) (FK1-->Employee) 
EmployeeID  (FK1-->Employee) 
Смежные вопросы