如果表中的数据需要基于行中的多个值具有唯一约束,则适合的解决方案将是复合健。
复合主键
使用SQL Server语法创建符合主键非常简单。
create table my_parts ( id_part1 int not null, id_part2 int not null, id_part3 int not null, primary key(id_part1,id_part2,id_part3) )GO
在已经存在的表的情况下,通过简单的查询,复合键约束也很容易。
ALTER TABLE my_parts ADD PRIMARY KEY (id_part1, id_part2,id_part3);GO
但是对于传统的现有系统,当您不允许在正在生产的系统中进行大的更改时,您必须通过简单地找到它们然后从表数据中删除它们来处理重复项。
这可能是一个真正的头痛,特别是如果现有数据对于实时系统运行至关重要
首先要找到重复的东西。
SELECT id_part1 , id_part2 , id_part3 , COUNT(*) AS [count]FROM dbo.my_parts (NOLOCK)GROUP BY id_part1 , id_part2 , id_part3HAVING COUNT(*) > 1;
复合唯一约束
在某些情况下,您可能有一个表的主键和一个复合键。在这种情况下,查找重复的查询对你没有什么用,因为您将获得所有复合键值的重复数量,但由于主键对于每一行都是唯一的,因此您不能通过在查询中包含主键来进行分组。
要获得这样的tbale,你需要采用一种不同的方法来创建它,以防你从头开始。
CREATE TABLE my_parts ( id INT IDENTITY(1,1) NOT NULL, id_part1 INT NULL , id_part2 INT NULL , id_part3 INT NULL , PRIMARY KEY CLUSTERED (id), CONSTRAINT [CK_my_parts] UNIQUE (id_part1,id_part2,id_part3) );GO
如果您正在处理现有数据库,该数据库已经包含要包含在复合唯一约束中的列值的重复项,则在添加约束之前,您需要从重复项中清除表。只有这样,您才能使用现有数据将复合唯一contrsint添加到existig表中。
DELETE FROM dbo.my_partsWHERE id NOT IN ( SELECT MIN(id) FROM dbo.my_parts GROUP BY id_part1 , id_part2 , id_part3 );