2012-06-19 8 views
1

У меня есть таблица Школа и стол Учитель, имеющий отношения «один ко многим». Однако одним из учителей является принцип школы, и только один учитель может быть школьным принципом. Так я думал о спасении учителей идентификатора (принцип) в таблице школы следующим образом:Как реализовать двунаправленные таблицы со ссылками?

CREATE TABLE School (
    ID INT PRIMARY KEY, 
    Name VARCHAR(40), 
    PrincipleID INT FOREIGN KEY REFERENCES Teacher.ID 
) 

CREATE TABLE Teacher (
    ID INT PRIMARY KEY, 
    Name VARCHAR(40), 
    SchoolID INT FOREIGN KEY REFERENCES School.ID 
) 

Я знаю, что я мог потерять внешний ключ ссылки в таблице школы, но это не вариант.

Должен ли я сделать ссылку после создания таблицы? Если да, то как?

+0

См. Мое редактирование, поэтому двунаправленное отношение не является хорошей практикой. –

+0

Я бы надеялся, что в школе много хороших принципов, но да, вы обычно хотите, чтобы только один человек занимал должность «принципала». –

ответ

3

Другим решением является создание новой таблицы, скажем, SchoolsPrinciples с помощью всего двух полей:

CREATE TABLE SchoolsPrinciples 
(
    SchoolId int, 
    TeacherId int, 
    CONSTRAINT uc_SchoolTeacher UNIQUE (SchoolId, TeacherId) 
) 

УНИКАЛЬНОЕ ограничение позволяет получить ровно одного учителя в каждой школе.

+0

УНИКАЛЬНО, на какой колонке? –

+0

@ADC - Вы набрали это быстрее, чем я - ALTER TABLE [dbo]. [SchoolsPrincipals] ADD CONSTRAINT UNQ__SchoolPrincipal__SchoolID UNIQUE ([SchoolID]) – user1166147

+0

Но это не остановит использование двух принципов. school1 + teacher1, school1 + teacher2 –

1

Положите булево IsPrincipal на таблицу Teacher. Или добавьте третью таблицу отношений

CREATE TABLE SchoolPrincipals (
    INT SchoolID PRIMARY KEY FOREIGN KEY REFERENCES School.ID, 
    INT TeacherID FOREIGN KEY REFERENCES Teacher.ID 
) 

Сохраняет все аккуратно, без болезненной логики удаления.

+1

Это позволит иметь несколько принципов в одной школе, и это требование иметь один принцип. –

+0

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

1

Вы можете взять столбец в таблице Учитель, как

  1. IsPrincipal где только одна строка будет иметь значение, как истинный, как говорится по jonnyGold,

     This can be checked by triggers. 
            OR 
         You can use filtered index if using Sql Server 2008. 
          Create unique filtered index where SchoolID, IsPrincipal 
          is NOT NULL and are unique 
    
  2. Boss, где это будет содержать идентификатор главным образом, создавая employee manager relationship, который в вашем случае не подходит.

CREATE TABLE EmpManager ( TeacherID INT SchoolID INT IsPrincipal бит ) и использовать фильтрованную индекс или триггер для обработки сценария.

EDIT:

CREATE TABLE [dbo].[Teacher](
    [ID] [int] NOT NULL primary key, 
    [Name] [varchar](40) NULL, 
    [SchoolID] [int] NULL, 
) 
GO 

CREATE TABLE [dbo].[School](
    [ID] [int] NOT NULL primary key, 
    [Name] [varchar](40) NULL, 
    [PrincipleID] [int] NULL, 
) 
GO 

ALTER TABLE [dbo].[Teacher] WITH CHECK ADD CONSTRAINT [FK_Teacher_School] FOREIGN KEY([SchoolID]) 
REFERENCES [dbo].[School] ([ID]) 
GO 

ALTER TABLE [dbo].[School] WITH CHECK ADD CONSTRAINT [FK_School_Teacher] FOREIGN KEY([PrincipleID]) 
REFERENCES [dbo].[Teacher] ([ID]) 
GO 

enter image description here

Лучше дизайн должен быть один предложенный АЦП

enter image description here

+0

Итак, вы говорите, что невозможно реализовать «двунаправленные» отношения таблиц? –

+0

@ DarDar: Это возможно. Связь сотрудника с менеджером является примером двунаправленных отношений. –

+0

Благодарим вас за ответ и усилие. Решение Аллана - это нечто похожее, и оно работает. Ваше решение также работает. Благодаря! Но во всяком случае, что было бы недостатком двунаправленных отношений? –

2

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

CREATE TABLE School (
    ID INT PRIMARY KEY, 
    Name VARCHAR(40), 
    PrincipleID INT); 

CREATE TABLE Teacher (
    ID INT PRIMARY KEY, 
    Name VARCHAR(40), 
    SchoolID INT 
     CONSTRAINT FK_Teacher_School 
     FOREIGN KEY REFERENCES School); 

ALTER TABLE School add 
    CONSTRAINT FK_School_Teacher 
    FOREIGN KEY (PrincipleID) REFERENCES Teacher; 

При добавлении данных, вам необходимо установить PrincipleID поле как отдельное обновление:

insert into School (ID, Name) 
values (1, 'Blarg Elementary'); 

insert into Teacher (ID, Name, SchoolID) 
values (1, 'John Doe', 1), 
     (2, 'Bob Smith', 1), 
     (3, 'Adam Walker', 1); 

update School set PrincipleID = 2 where ID = 1; 
+0

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

+1

+1 команда ALTER TABLE - как добавить ссылку после создания таблицы. – LesterDove

+1

Спасибо за ваш ответ! Это то, что я искал. –

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