有城市,工作类型和任务。城市可以有多种工作类型。为可以具有多个作业类型的城市创建任务。城市可以有很多任务。但是,在为分配给城市的任务添加作业类型时,必须确保城市具有该作业类型。
如何在添加/更新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
如何在添加/更新Task_JobTypes时创建关系/约束以确保与任务关联的City在City_JobTypes中允许该作业类型?
您可以使用调用函数的CHECK CONSTRAINT执行此操作。该函数将TaskID
和JobTypeID
作为参数,并查询连接到Tasks
表的City_JobTypes
表,看看City
是否有JobType
。然后,如果城市有工作类型,函数将返回True (1)
,如果没有,则返回false (0)
。
或者,您也可以使用TRIGGER执行此操作,但我更喜欢CHECK CONSTRAINTS。
在我看来,你在哲学上反对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↗