如何在SQL Server中使两列唯一?

3

大家好,

我想知道如何以我下面所解释的特殊方式,在SQL服务器中使两列唯一。

我的需求是:

------------------------- 
  User    | Friend      |  
-------------------------
  Stevan  | Johns     } 
  William | David     }This is how I want two columns to be unique. 

我不想的方式:

-------------------------
  User    | Friend    | 
-------------------------
 Steven   | Johns     }   
 Johns    | Steven    }This must not allow.

Steven 是 Johns 的朋友,因此他们是朋友,所以我不希望 Johns 添加一行新的内容,说 Johns 是 Steven 的朋友。

Steven 添加新的一行内容如下:

-------------------------
  User    | Friend    | 
-------------------------
 Steven   | Johns     }   

我不希望John再像这样添加一行

-------------------------
  User    | Friend    | 
-------------------------
 Steven   | Johns     }   
 Johns    | Steven    }

希望我的问题表达清楚了,如果有人知道一个好的答案,请帮帮我。 非常感谢任何回答提前


那么,“User”列和“Friend”列之间没有什么特别的区别吗? - Damien_The_Unbeliever
我已经尝试过那种方法,但我更喜欢使用约束。有没有适用于这种情况的约束条件? - Real Programmer
我的意思是,一个名字出现在“用户”而不是“朋友”中的唯一原因是他们是第一个进行插入操作的人 - 如果朋友先执行了插入操作(所以名字顺序相反),这不会导致任何一个人被特别对待,对吧? (请参见我的答案 - 其中第一个建议涉及强制表中的第一个名称为<第二个名称 - 但仅当我们可以(如果需要)在插入之前切换名称时才有效) - Damien_The_Unbeliever
@user2249029:名称可能存在重复的可能性。 可能会有两个约翰。 如果您的名称是唯一的,则可以继续进行。 否则,为每个人创建一个唯一类型的ID。 - SenthilPrabhu
用户或好友列本身并不是唯一的,但它们作为两者的组合是唯一的。 - Real Programmer
显示剩余2条评论
2个回答

4

在所有其他条件相等的情况下,实现这一点的简单方法是坚持认为第一列中的值始终比第二列中的值更早排序:

CREATE TABLE Friends (
    Party1 varchar(20) not null,
    Party2 varchar(20) not null,
    constraint CK_Friend_Parties CHECK (Party1 < Party2),
    constraint CK_Friends_Unique UNIQUE (Party1,Party2)
)

如果您无法适应此更改(这很奇怪,因为它表明关系不对称),则可以通过索引视图来强制执行:

create table dbo.T1 (
    Party1 varchar(20) not null,
    Party2 varchar(20) not null
)
go
create view dbo.V1
with schemabinding
as
    select
        CASE WHEN Party1 < Party2 THEN Party1 else Party2 END as NormParty1,
        CASE WHEN Party1 < Party2 THEN Party2 else Party1 END as NormParty2
    from
        dbo.T1
go
create unique clustered index IX_V1 on dbo.V1 (NormParty1,NormParty2)
go
insert into dbo.T1 (Party1,Party2) values ('Steven','John')
go
insert into dbo.T1 (Party1,Party2) values ('John','Steven')

上述最后一个插入语句出现了错误。需要注意的是,大多数情况下,您可以忽略视图V1——它仅存在于强制执行此约束时使用(当我使用这样的表时,通常会在其名称前加上DRI_以清楚地表示它并非真正创建用于查询。


-1

我认为,因为主键无法起作用,你将不得不使用触发器来检查该行是否已经存在。


如果你想成为语法纳粹并纠正别人,请确保语法正确。这是一个复杂的句子,但我已经简化了它,以方便非英语母语者。 - wazaminator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接