UNIQUE约束,仅当字段包含特定值时

时间:2011-02-10 10:09:04

标签: mysql unique-constraint

我正在尝试为两列创建UNIQUE INDEX约束,但仅当另一列包含值1.例如,column_1column_2仅在{{1}时才应为UNIQUE }。包含active = 1的任何行都可以与另一行共享active = 0column_1的值,而不管column_2的其他行的值是什么。但active无法与另一行active = 1共享column_1column_2值的行。

我的意思是“共享”是两行在同一列中具有相同的值。示例:row1.a = row2.a AND row1.b = row2.b.仅当row1中的两列与row2中的其他两列匹配时,才会共享值。

我希望自己清楚明白。 :\

6 个答案:

答案 0 :(得分:13)

您可以尝试使用column_1,column_2和active激活创建多列UNIQUE索引,然后为不需要唯一性的行设置active = NULL。或者,您可以使用触发器(see MySQL trigger syntax) 如果这些值已经在表中,则检查每个插入/更新的行 - 但我认为它会相当慢。

答案 1 :(得分:4)

  

我试图为两列创建一个UNIQUE INDEX约束,但仅当另一列包含值1

您可以设置"另一列"的值到一个不等于1的唯一值,例如记录的id。

然后,唯一索引约束可以应用于所有三列,包括"另一列"。让我们调用另一列"" columnX。 如果要将唯一约束应用于记录,请将columnX的值设置为1。如果您不想应用唯一约束,请将columnX的值设置为唯一值。

然后不需要额外的工作/触发器。所有三列的唯一索引可以解决您的问题。

答案 2 :(得分:0)

索引与外部影响无关。这种约束必须在数据库之外实现。

答案 3 :(得分:0)

在SQL Server中,这可以通过检查约束来完成,但我不知道MySQL是否支持类似的任何内容。

在任何数据库上都可以使用的是,您可以将表拆分为两个。如果active = 0的记录只是历史记录,并且永远不会再次激活,您可以将它们移动到另一个表,并在原始表上设置一个简单的唯一约束。

答案 4 :(得分:0)

我不确定 MySQL 语法,但它应该具有与 SQL Server 几乎相同的东西:

CREATE UNIQUE INDEX [UNQ_Column1Column2OnAtive_MyTable]
  ON dbo.[MyTable]([column1,column2)
  WHERE   ([active] = 1);

该索引将确保如果 active=1 那么 column1 和 column2 组合在整个表中是唯一的。

答案 5 :(得分:0)

我不确定我是否 100% 理解您,但假设您有一个包含状态列的表,并且您想确保只有一个状态为“A”(活动)的原始数据。您可以处理许多状态为“I”或“Z”或其他任何内容的行。状态为“A”的仅允许一行。

这样就可以了。

  CREATE UNIQUE INDEX [Idx_EvalHeaderOnlyOneActive]
  ON [dbo].[EvalHeader]([Hdr Status])
  WHERE [Hdr Status] = 'A';