非规范化的多对多映射

时间:2011-04-12 16:13:46

标签: sql-server sql-server-2008 normalization unique-index

在SQL Server 2008 R2中,我有一个具有以下结构的表

(
  Id     INT NOT NULL PRIMARY KEY,
  Left1  INT NOT NULL,
  Left2  INT NULL,
  Right1 NVARCHAR(128) NOT NULL,
  Right2 NVARCHAR(128) NOT NULL,
  Right3 NVARCHAR(128) NULL,
  Right4 NVARCHAR(128) NULL,
  Right5 NVARCHAR(128) NULL,
  Right6 NVARCHAR(128) NULL
)

用于映射Left1和Left2,从系统(“Left”)到Right1-6,转到另一个系统(“Right”)。

我需要确保Left列是唯一的,我使用唯一索引完成,左右组合也是唯一的。

我不能在这里使用索引,因为支持的最大列大小是900字节。我需要避免在Left,Right和Left2Right中拆分表格 - 因为我的用例太麻烦且容易出错。

强制执行组合唯一性的正确方法是什么?


我的要求是:

  • 在整个表中,左边和左边的任何行都必须没有相同的值(已解决)
  • 在整个表中,左边,左边,右边1,右边2,右边3,右边4,右边5,右边6都不能有相同值的行(我需要帮助)

2 个答案:

答案 0 :(得分:4)

完全没必要添加第二个约束。

您对

的独特约束

Left1, Left2

将阻止

的重复值

Left1, Left2, Right1, Right2, Right3, Right4, Right5, Right6

如果没有先复制前2个字段,就无法复制所有8个字段。

答案 1 :(得分:1)

一个想法:创建一个包含所有可能“正确”值的查找表,为它们分配整数代理键,在Left2Right表中使用这些代理键,并在它们上构建唯一约束。非正规化和丑陋的罪恶,但它可以做到这一点。


(添加)

您还可以尝试构建值的哈希值并对其进行约束。穷人的版本是使用校验和添加一个钙化的行:

ALTER TABLE MyTable
 Add RightHash AS checksum(Left1, Left2, Right1, Right2, Right3, Right4, Right5, Right6)

并在其上添加一个唯一约束(它可能必须是一个持久计算列才能执行此操作)。这个问题的主要问题是不同的初始值集合可能产生相同的校验和值。您可以通过hashbytes函数使用其中一个(更多)健壮的散列算法,这将具有相同的限制(可能的重复散列值),但碰撞的可能性会小得多。