Sql server 非有向图的唯一约束格式-给定(1,2),防止(2,1)

Sql server 非有向图的唯一约束格式-给定(1,2),防止(2,1),sql-server,sql-server-2008,constraints,Sql Server,Sql Server 2008,Constraints,我的SQL Server(2008)数据库中有一个非定向图表,我需要一个约束来防止重复。 我的链接表有两列(City1、City2),两列都引用到Cities表中。我可以使用以下方法: ALTER TABLE dbo.CityConnections ADD CONSTRAINT CK_CityConnections_OneWayOnly UNIQUE (City1, City2) 这是我想要的一半,但这并不妨碍添加“反向”连接 谷歌给我看了 ... UNIQUE (MIN(City1,City

我的SQL Server(2008)数据库中有一个非定向图表,我需要一个约束来防止重复。 我的链接表有两列(City1、City2),两列都引用到Cities表中。我可以使用以下方法:

ALTER TABLE dbo.CityConnections
ADD CONSTRAINT CK_CityConnections_OneWayOnly UNIQUE (City1, City2)
这是我想要的一半,但这并不妨碍添加“反向”连接

谷歌给我看了

... UNIQUE (MIN(City1,City2), MAX(City1,City2))
看起来它会完全符合我的要求,但语法无效

我还尝试了一个复杂的约束用例,但我也不能得到正确的语法


我如何才能做到这一点?

假设您可以控制表中的条目,下面的方法应该可以奏效

ALTER TABLE dbo.CityConnections
ADD CONSTRAINT CK_CityConnections_Unq UNIQUE (City1, City2)
ALTER TABLE dbo.CityConnections
ADD CONSTRAINT CK_CityConnections_OneWayOnly CHECK (City1 < City2)
ALTER表dbo.CityConnections
添加约束CK_CityConnections_Unq UNIQUE(City1,City2)
ALTER表dbo.CityConnections
添加约束检查城市连接单向检查(城市1<城市2)

假设您可以控制表中的条目,下面的操作应该有效

ALTER TABLE dbo.CityConnections
ADD CONSTRAINT CK_CityConnections_Unq UNIQUE (City1, City2)
ALTER TABLE dbo.CityConnections
ADD CONSTRAINT CK_CityConnections_OneWayOnly CHECK (City1 < City2)
ALTER表dbo.CityConnections
添加约束CK_CityConnections_Unq UNIQUE(City1,City2)
ALTER表dbo.CityConnections
添加约束检查城市连接单向检查(城市1<城市2)

太好了,只要我问了一个困扰我很久的问题,我就会得到灵感并自己解决。 我的解决方案是添加计算列并将其用作唯一约束(索引)

我现在有:

CREATE TABLE [CityConnections]
(
    [City1] [int] NOT NULL,
    [City2] [int] NOT NULL,
    [minCity]  AS (case when [City1]<[City2] then [City1] else [City2] end),
    [maxCity]  AS (case when [City1]>[City2] then [City1] else [City2] end),
CONSTRAINT [CK_CityConnections_OneWayOnly] UNIQUE NONCLUSTERED 
(
    [minCity] ASC,
    [maxCity] ASC
)
创建表[城市连接]
(
[City1][int]不为空,
[City2][int]不为空,
[minCity]如同(当[City1][City2]然后[City1]其他[City2]结束时的情况),
约束[CK_CityConnections_OneWayOnly]唯一非聚集
(
[minCity]ASC,
[maxCity]ASC
)

编辑-进一步思考(和评论)后,我同意这不是最好的解决方案

太好了,只要我问了一个困扰我很久的问题,我就会得到灵感,自己想出来。 我的解决方案是添加计算列并将其用作唯一约束(索引)

我现在有:

CREATE TABLE [CityConnections]
(
    [City1] [int] NOT NULL,
    [City2] [int] NOT NULL,
    [minCity]  AS (case when [City1]<[City2] then [City1] else [City2] end),
    [maxCity]  AS (case when [City1]>[City2] then [City1] else [City2] end),
CONSTRAINT [CK_CityConnections_OneWayOnly] UNIQUE NONCLUSTERED 
(
    [minCity] ASC,
    [maxCity] ASC
)
创建表[城市连接]
(
[City1][int]不为空,
[City2][int]不为空,
[minCity]如同(当[City1][City2]然后[City1]其他[City2]结束时的情况),
约束[CK_CityConnections_OneWayOnly]唯一非聚集
(
[minCity]ASC,
[maxCity]ASC
)

编辑-经过进一步思考(和评论),我同意这不是最好的解决方案。这是我通常建议的。或者,可以添加触发器,以便插入和更新可以按任意顺序进行。为了完整性,我的触发器如下所示:
CREATE TRIG_CityConnection_Insert ON[CityConnections]代替插入为开始设置无计数;插入[CityConnections]选择(当[City1]<[City2]然后[City1]其他[City2]结束时的情况)作为城市1,(当[City1]>[City2]然后[City1]其他[City2]结束时的情况)作为插入的City2;END
+1。这是我通常建议的。或者,可以添加触发器,以便插入和更新可以按任意顺序进行。为了完整起见,我的触发器如下所示:
CREATE TRIG\u CityConnection\u Insert ON[CityConnections]代替插入为开始设置无计数;插入[CityConnections]选择(当[City1]<[City2]然后[City1]其他[City2]结束时的情况)作为城市1,(当[City1]>[City2]然后[City1]其他[City2]结束时的情况)由于City2 FROM inserted;END
创建的索引仅支持
CK_CityConnections\u单向
在这里是完全浪费的,除非您的查询引用
minCity,maxCity
,如果他们这样做了,为什么要存储
City1,City2
?MarkD的答案似乎更有效。“下面的答案”在此处引用答案是一种不好的方式-答案会根据投票情况改变位置。如果您希望引用其他人的答案,通常最好链接到该答案(每个答案下面都有一个共享链接,您可以从中复制适当的链接地址)。实际上,进一步考虑后,我同意计算列是一团乱(我更愿意在约束中计算它们)此外,正如您所指出的,约束实际上变成了一个有效的索引。创建用于支持
CK\u CityConnections\u单向
的索引在这里是完全浪费的,除非您的查询引用
minCity,maxCity
,如果是,为什么要存储
City1,City2
?MarkD的答案似乎更有效。“下面的答案”是在此处引用答案的一种不好的方式-答案会根据投票情况改变位置。如果您希望引用其他人的答案,通常最好链接到该答案(每个答案下面都有一个共享链接,您可以从中复制适当的链接地址)实际上,在进一步考虑之后,我同意计算列是一团乱(我更愿意在约束中计算它们),而且,正如您所指出的,约束实际上变成了一个高效的索引