使用Composite Key或Unique Constraint来防止行重复

时间:2014-03-10 21:22:19

标签: sql-server tsql

我的表和数据如下所示:这些数据来自Archive。

Table with duplicate row

我使用ROW_NUMBER() OVER(PARTITION BY Values)获取单行。但是,我想在表中添加CONSTRAINT以防止重复插入。

由于数据是多对多业务规则,我想我可以使用包含Composite Key的{​​{1}}和所有4个附加列。

我正在考虑以下三个选项:

  1. 我是否应该使用包含以下所有列的CONSTRAINT
  2. 使用包含列
  3. 的复合键
  4. 添加一个唯一列(Clustered Index),然后对其余列使用约束。
  5. 但是,使用复合材料我仍然可以插入重复的行。

    这里有什么更好的方法?

3 个答案:

答案 0 :(得分:2)

tl; dr 具有唯一约束的主键应该是一个很好的方法。

您绝对应该添加一个新列作为主键。一个标识栏就可以了。类似的东西:

ALTER TABLE table_1
   ADD id INT IDENTITY;

ALTER TABLE table_1
   ADD CONSTRAINT PK_table_1
   PRIMARY KEY(id);

这样做的原因是它可以更容易地将行跟踪为单个实体,因此您可以更轻松地执行更新和删除。另外,它对第3范式非常有用。

主键不一定是聚集索引,顺便说一句。虽然默认情况下会为SQL Server中的主键自动创建聚簇索引(如果表中没有聚簇索引)。

获得主键后,可以对其他列使用UNIQUE约束。假设您可以使用默认的系统错误消息。如果您需要更多根据您的需求定制的错误消息,您将需要使用INSTEAD OF TRIGGER。

我会避免使用包含所有列的聚簇唯一索引。当您插入新记录时,这将导致大量碎片和磁盘IO。一个非聚集的唯一索引就可以了,但那时你基本上得到了一个约束。

答案 1 :(得分:2)

最简单(也可能是最好)的方法是在四列上放置一些独特的约束。有三种方法可以做到这一点:

  • 主键
  • 唯一索引
  • 唯一约束

主键和唯一键之间的唯一区别是uniques将允许可为空的列;我发现的独特之处的唯一区别在于它们是如何定义的(索引与约束),底层机制是相同的。既然你得到了一个索引,我就会坚持使用索引定义。

使用哪个取决于(a)是否可以为任何列,以及(b)如何使用该表 - 也就是说,它如何从索引中受益最佳。集群,列的顺序(考虑基数),插入和更新的频率......通常的东西。

答案 2 :(得分:1)

取决于您的优化内容:插入性能与查询性能,存储,查询的复杂性等。

如果没有任何其他信息,我建议选项#3:添加surrogate PK列并使用单独的约束强制其他4列的唯一性。考虑JOIN到其他表的示例 - 代理键将确保您只需要在连接谓词中包含一列而不是五列。