2015-04-15 34 views
1

我得到了三张表。如何建立外键关系

User 
Project 
WorkFlow 

在工作流程专案编号,用户ID一起不应该重复。那就是我的 的要求。我的意思是这个组合不应该重复。

而ProjectId应出现在项目表中并且UserId 应出现在用户表中。

这是要求。

步骤i尝试:

我制成ProjectId, UserId如在工作流复合键。但无法维护外键,因为两列在单表中不可用。

如何解决这个问题。

我也愿意改变我的设计,因为这是我发展的初始阶段。

主要reuirement是

一个表存储项目(项目表)相关的信息和 另一个(工作流程)持有该项目分配给 该用户的记录。

+0

您还可以使用UNIQUE KEY CONSTRAINT或UNIQUE(集群或非集群)INDEX来强制执行非PK列的唯一性吗? – StuartLC

+0

@StuartLC那么可以删除组合键并将这两列作为唯一键? – shanmugharaj

+1

是的,就像@罗杰的答案在下面(+1),尽管建议你命名UKC。 – StuartLC

回答

2

外键不控制唯一性;他们只控制参照完整性。对于唯一性,需要唯一约束:

create table dbo.Workflow (
    Id int identity(1,1) primary key, 
    ProjectId int not null, 
    UserId int not null, 
    foreign key (ProjectId) references dbo.Project (Id), 
    foreign key (UserId) references dbo.[User] (Id), 
    unique (UserId, ProjectId) 
); 

编辑:如果您不需要在此表中的代理键,不要在意它的可能的孩子,你可以通过切换简化结构从代理主键到自然主键。随着表变得越来越窄,这将减少其占用磁盘空间增加高负载情况下的性能:

create table dbo.Workflow (
    ProjectId int not null, 
    UserId int not null, 
    primary key (UserId, ProjectId) 
    foreign key (ProjectId) references dbo.Project (Id), 
    foreign key (UserId) references dbo.[User] (Id), 
); 

是的,约束应该唯一命名的,它将使模式比较和更新更加容易。

+0

嗨,感谢您的回复..是的外键不会使唯一性我只需要它的参照完整性。很好,我会将这些变成独特的密钥 – shanmugharaj

+0

答案大部分是正确的,但是有一个错误,新来者使用**关联表**。这里'id'字段和索引是完全多余的,它没有任何用处。它是一个PK的概念是用'id'字段标记每个文件并将其声明为“PK”,这是错误的。删除'id'字段和索引。然后使'(UserId,ProjectId)'主键。因为它是。 – PerformanceDBA

+0

@ PerformanceDBA,通常你会是对的。然而,从主题领域来看,我决定OP很可能会在这一个下面有一些表格。而且因为大多数人都有理解多列外键的问题,所以我决定添加代理PK。如果我的猜测是正确的,它也将解决“移动”问题(切换到另一个项目/用户),否则将导致PK更新并需要'更新级联',这通常是不合需要的。但是,这只是一个猜测。 –