Отношение SQL к вторичной таблице без добавления повторяющегося столбца - PullRequest
0 голосов
/ 06 сентября 2018

Есть города, типы работ и задачи. Города могут иметь несколько типов заданий. Задачи создаются для города, который может иметь несколько типов заданий. Города могут иметь много задач. Но при добавлении типов работ для задач, назначенных городу, необходимо убедиться, что город имеет этот тип работы.

Как создать отношение / ограничение при добавлении / обновлении Task_JobTypes, чтобы убедиться, что для города, связанного с задачей, этот тип задания разрешен в City_JobTypes? Ограничение в Task_JobTypes "FK_Task_JobTypes_JobTypes" должно ссылаться на него, а не только на JobTypes.

Города - Id, Название

JobTypes - Id, Name

CityJobTypes - CityId, JobTypeId (разрешенные типы заданий на город)

Задачи - Id, CityId, Имя (Задача для города)

TaskJobTypes - TaskId, JobTypeId (JobTypes per Task)

Таблицы -

CREATE TABLE [dbo].[Cities](
    [Id] [int] IDENTITY(1,1) NOT NULL,  
    [Name] [varchar](500) NOT NULL, 
CONSTRAINT [PK_Cities] PRIMARY KEY CLUSTERED ([Id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO    

CREATE TABLE [dbo].[JobTypes](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](50) NOT NULL
 CONSTRAINT [PK_JobTypes] PRIMARY KEY CLUSTERED ([Id] ASC)
 WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO    

CREATE TABLE [dbo].[City_JobTypes](
    [JobTypeId] [int] NOT NULL,
    [CityId] [int] NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[City_JobTypes]  WITH CHECK ADD  CONSTRAINT [FK_City_JobTypes_Cities] FOREIGN KEY([CityId])
REFERENCES [dbo].[Cities] ([Id])
GO    

ALTER TABLE [dbo].[City_JobTypes]  WITH CHECK ADD  CONSTRAINT [FK_City_JobTypes_JobTypes] FOREIGN KEY([JobTypeId])
REFERENCES [dbo].[JobTypes] ([Id])
GO 

CREATE TABLE [dbo].[Tasks](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [CityId] [int] NOT NULL,
    [Name] [varchar](50) NOT NULL,
 CONSTRAINT [PK_Tasks] PRIMARY KEY CLUSTERED ([Id] ASC)
 WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Tasks]  WITH CHECK ADD  CONSTRAINT [FK_Tasks_Cities] FOREIGN KEY([CityId])
REFERENCES [dbo].[Cities] ([Id])
GO

CREATE TABLE [dbo].[Task_JobTypes](
    [TaskId] [int] NOT NULL,
    [JobTypeId] [int] NOT NULL,
 CONSTRAINT [IX_Task_JobTypes-TaskId,JobTypeId] UNIQUE NONCLUSTERED 
(
    [TaskId] ASC,
    [JobTypeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Task_JobTypes]  WITH CHECK ADD  CONSTRAINT [FK_Task_JobTypes_JobTypes] FOREIGN KEY([JobTypeId])
REFERENCES [dbo].[JobTypes] ([Id])
GO

ALTER TABLE [dbo].[Task_JobTypes]  WITH CHECK ADD  CONSTRAINT [FK_Task_JobTypes_Tasks] FOREIGN KEY([TaskId])
REFERENCES [dbo].[Tasks] ([Id])
GO

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Мне кажется, что вы философски возражаете против composite keys. Таблица ссылок City_JobTypes имеет составной первичный ключ CityId, JobTypeId. Любая другая таблица, ограничивающая City_JobTypes, должна ограничиваться ее первичным ключом. Это два столбца, но это все еще один ключ. Я не вижу там проблемы.


Я вижу твою структуру ...

A Task принадлежит одному City и имеет один JobType.

Поскольку работа должна иметь один City и один JobType, сделайте эти атрибуты Task?

City
 ↑
Task → JobType


A City также имеет 0..мани JobTypes, что "разрешено".

City ← City_JobTypes
 ↑          ↓
Task → JobType


На данный момент ваша таблица Task уже имеет CityID и JobTypeID.

Почему бы не связать этот составной ключ с таблицей City_JobTypes?

City ← City_JobTypes
 ↑   ↗      ↓
Task → JobType


Если один Task действительно может иметь 0..мани JobTypes ...

Я бы начал здесь, который никак не может ограничить Tasks на основе ссылок City_JobType ...

City ← City_JobTypes↘
 ↑                   JobType
Task ← Task_JobTypes↗

Тогда я бы решил, что Task может быть разумно идентифицирован как CityTask с составным первичным ключом. Это позволило бы следующее.

   City  ←    City_JobTypes ↘
   ↑          ↑     ↑        JobType
CityTask ← CityTask_JobTypes↗
0 голосов
/ 06 сентября 2018

Как создать связь / ограничение при добавлении / обновлении Task_JobTypes, чтобы убедиться, что город, связанный с задачей, имеет Тип работы разрешен в City_JobTypes?

Вы можете сделать это с помощью CHECK CONSTRAINT , которая вызывает функцию. Функция будет принимать TaskID и JobTypeID в качестве параметров и запрашивать таблицу Tasks, присоединенную к таблице City_JobTypes, чтобы определить, есть ли у City эта JobType. Тогда функция вернет True (1), если в городе есть тип задания, или false (0), если нет.

С другой стороны, вы также можете сделать это с помощью TRIGGER, но я предпочитаю ПРОВЕРИТЬ ОГРАНИЧЕНИЯ лично.

...