【发布时间】:2018-09-06 13:41:41
【问题描述】:
有城市、工作类型和任务。城市可以有多种工作类型。为可以具有多种工作类型的城市创建任务。城市可以有许多任务。但是在为分配给城市的任务添加工作类型时,必须确保城市具有该工作类型。
如何在添加/更新 Task_JobTypes 时创建关系/约束以确保与任务关联的城市在 City_JobTypes 中允许该职位类型? Task_JobTypes "FK_Task_JobTypes_JobTypes" 中的约束需要引用它而不仅仅是 JobTypes。
城市 - ID、名称
工作类型 - ID、姓名
CityJobTypes - CityId,JobTypeId(每个城市允许的工作类型)
任务 - Id,CityId,Name(城市任务)
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
【问题讨论】:
-
为什么“不添加重复列”?没有这些信息,就无法完成。您应该将
JobType添加到与城市关联的任务列表中。然后,您可以使用复合键将其限制在您需要的所有表中。 -
只是向 TaskJobTypes 添加另一列 (CityId) 来引用任务已经引用的城市,这似乎是多余的。其他一切都已经有关系,这是唯一的方法吗?这只是数据库中许多具有此类设置的表的一个示例,并且添加额外的列似乎只是多余的,但如果它是唯一的选择(或最简单/最干净),这就是我想要看到的
-
有时,如果我要向表中添加另一列以强制执行此类约束(如此处的
CityId),我会将表命名为_TaskJobTypes,而将列命名为_CityId,然后创建一个名为TaskJobTypes的视图来隐藏该列(加上在INSERT/UPDATE期间填充该列的触发器)。 你知道你的数据库有额外的列,你数据库的用户不需要(因为他们仍然只是INSERT/UPDATE/DELETE针对该视图而不是表格)
标签: sql sql-server foreign-keys constraints relationship