如何使用约束强制两个子项来自同一父项?

How to use constraints to force two child items be from the same parent?

我有 2 个作业,每个作业有 3 个任务,并且在作业中任务是相关的,如图所示。 Task_Relationships table 表示作业中的任务之间存在依赖关系。

如何确保当我向 Task_Relationships 添加条目时 table say (1,2) 代表任务 1 与任务 2 相关的事实,任务 1 和 2 是在同一份工作?我试图通过键而不是代码来强制执行此操作。

drop table if exists dbo.test_jobs
create table dbo.test_jobs (
    [Id] int identity(1,1) primary key not null,
    [Name] varchar(128) not null
)

drop table if exists dbo.test_tasks  
create table dbo.test_tasks (
    [Id] int identity(1,1) primary key not null,
    [Job_Id] int not null,
    [Name] varchar(128) not null
    constraint fk_jobs foreign key ([Id]) references dbo.test_jobs(Id)
)

drop table if exists dbo.test_task_relationships 
create table dbo.test_task_relationships (
    [Id] int identity(1,1) not null,
    [From_Task] int not null,
    [To_Task] int not null
    constraint fk_tasks_from foreign key ([From_Task]) references dbo.test_tasks(Id),
    constraint fk_tasks_to foreign key ([To_Task]) references dbo.test_tasks(Id)
)

依赖标识列作为主键对您没有帮助。在关系 table IMO 中使用标识列是逻辑错误。当然,您不打算允许多个行存在于 table 中,并且 .

具有相同的值

假设 child table 定义为:

create table dbo.test_tasks (
    Job_Id int not null,
    Task_Id tinyint not null,
    Name varchar(128) not null,
    constraint pk_tasks primary key clustered (Job_Id, Task_Id),
    constraint fk_jobs foreign key ([Job_Id]) references dbo.test_jobs(Id)
);

现在你们的关系table可以转化为:

create table dbo.test_task_relationships (
    From_Job int not null,
    From_Task tinyint not null,
    To_Job int not null,
    To_Task tinyint not null
);

我会把它留给你来完成 DDL,但这应该会使你的目标微不足道。

您可以在 Task table 中声明一个超级键,其中包括 Job_Id 列以及现有键中的列。

create table dbo.test_tasks (
    [Id] int identity(1,1) primary key not null,
    [Job_Id] int not null,
    [Name] varchar(128) not null
    constraint fk_jobs foreign key ([Id]) references dbo.test_jobs(Id),
    constraint UQ_Tasks_WithJob UNIQUE (Id, Job_Id)
)

然后您可以将 Job_Id 列添加到关系 table 并将其包含在两个外键约束中:

create table dbo.test_task_relationships (
    [Id] int identity(1,1) not null,
    [From_Task] int not null,
    Job_Id int not null,
    [To_Task] int not null
    constraint fk_tasks_from foreign key ([From_Task], Job_Id) references dbo.test_tasks(Id, Job_Id),
    constraint fk_tasks_to foreign key ([To_Task], Job_Id) references dbo.test_tasks(Id, Job_Id)
)

table 现在无法包含不匹配的任务。如有必要,如果您不想将 job_id 列的存在暴露给应用程序并在插入期间自动填充它,请将此 table 包装在 view/trigger 中。