不添加重复列的SQL与辅助表的关系

问题描述 投票:0回答:2

有城市,工作类型和任务。城市可以有多种工作类型。为可以具有多个作业类型的城市创建任务。城市可以有很多任务。但是,在为分配给城市的任务添加作业类型时,必须确保城市具有该作业类型。

如何在添加/更新Task_JobTypes时创建关系/约束以确保与任务关联的City在City_JobTypes中允许该作业类型? Task_JobTypes“FK_Task_JobTypes_JobTypes”中的约束需要引用而不仅仅是JobTypes。

城市 - Id,名称

JobTypes - Id,Name

CityJobTypes - CityId,JobTypeId(每个城市允许的工作类型)

任务 - Id,CityId,名称(城市任务)

TaskJobTypes - TaskId,JobTypeId(每个任务的JobTypes)

表 -

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
sql sql-server foreign-keys constraints relationship
2个回答
0
投票

如何在添加/更新Task_JobTypes时创建关系/约束以确保与任务关联的City在City_JobTypes中允许该作业类型?

您可以使用调用函数的CHECK CONSTRAINT执行此操作。该函数将TaskIDJobTypeID作为参数,并查询连接到Tasks表的City_JobTypes表,看看City是否有JobType。然后,如果城市有工作类型,函数将返回True (1),如果没有,则返回false (0)

或者,您也可以使用TRIGGER执行此操作,但我更喜欢CHECK CONSTRAINTS。


0
投票

在我看来,你在哲学上反对composite keys。链接表City_JobTypes有一个复合主键CityId, JobTypeId。任何其他限制City_JobTypes的表都需要约束其主键。这恰好是两列,但它仍然是一个单独的键。我没有看到那里的问题。

我看到你的结构的方式是......

Task属于单个City并且有一个JobType

作为一个工作必须有一个City和一个JobType,制作Task的那些属性?

City
 ↑
Task → JobType

一个City也有0..many JobTypes,它是“允许的”。

City ← City_JobTypes
 ↑          ↓
Task → JobType

在这一点上你的Task表已经有一个CityID和一个JobTypeID

为什么不将该复合键约束到City_JobTypes表?

City ← City_JobTypes
 ↑   ↗      ↓
Task → JobType

如果一个Task实际上可以有0..many JobTypes ...

我从这里开始,没有任何办法,我可以看到基于Tasks链接限制City_JobType ...

City ← City_JobTypes↘
 ↑                   JobType
Task ← Task_JobTypes↗

然后我决定将Task合理地识别为具有复合主键的CityTask。这将允许以下内容。

   City  ←    City_JobTypes ↘
   ↑          ↑     ↑        JobType
CityTask ← CityTask_JobTypes↗
© www.soinside.com 2019 - 2024. All rights reserved.