sql - 不添加重复列与辅助表的 SQL 关系
问题描述
有城市、工作类型和任务。城市可以有多种工作类型。为可以具有多种工作类型的城市创建任务。城市可以有许多任务。但是在为分配给城市的任务添加工作类型时,必须确保该城市具有该工作类型。
添加/更新 Task_JobTypes 时如何创建关系/约束以确保与任务关联的城市在 City_JobTypes 中允许该职位类型?Task_JobTypes "FK_Task_JobTypes_JobTypes" 中的约束需要引用它而不仅仅是 JobTypes。
城市 - ID、名称
JobTypes - 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
解决方案
在我看来,您在哲学上反对composite keys
. 链接表City_JobTypes
有一个复合主键CityId, JobTypeId
。任何其他约束的表都City_JobTypes
需要约束其主键。那恰好是两列,但它仍然是一个键。我没有看到那里的问题。
我看到你的结构的方式是......
ATask
属于一个单一的City
并且有一个单一的JobType
。
作为一个Job必须有一个 City
和一个 JobType
,做出那些属性的Task
?
City
↑
Task → JobType
ACity
也有 0..manyJobTypes
它是“允许的”。
City ← City_JobTypes
↑ ↓
Task → JobType
此时你的Task
表已经有了 aCityID
和 a JobTypeID
。
为什么不将复合键限制在City_JobTypes
表上呢?
City ← City_JobTypes
↑ ↗ ↓
Task → JobType
如果一个单Task
人实际上可以有 0..many JobTypes
...
我将从这里开始,我看不到任何方式来限制Tasks
基于City_JobType
链接的...
City ← City_JobTypes↘
↑ JobType
Task ← Task_JobTypes↗
然后我决定Task
可以合理地将其标识为CityTask
具有复合主键的 a 。这将允许以下内容。
City ← City_JobTypes ↘
↑ ↑ ↑ JobType
CityTask ← CityTask_JobTypes↗
推荐阅读
- git - 当 Webhook 向 Jenkins 服务器发送请求以进行构建时,NET_ERR 从 Jenkins 服务器响应
- ruby-on-rails - 如何将 rspec 用于 sidekiq 企业定期作业?
- python - 选择行和列 pandas 中的下一个 nan 值
- javascript - 如何导入 Joomla!自定义文件中的 JFactory
- javascript - Jquery 确认删除使用 noty js 不起作用
- php - 使用php计算多个复选框和价格
- java - 使用三角形条带纹理球体的问题
- linux - 当我在 azure devops 服务器 shell 脚本任务中传递变量(路径)时,路径打印不带“/”
- javascript - 在 echarts 中的数据和标记线之间切换
- python - 使用 PypeR 从 Python 内部执行 R 文件