MySQL 仅对特定值的特定唯一约束

MySQL specific unique constraint only on specific values

我有一个包含这些字段的 table:

id, field_a, field_b, 状态 我对 (field_a, field_b, status)

有唯一约束

我正在使用状态(映射为整数)来管理软删除,因此,当我需要将项目标记为已删除时,我会更新相应值的状态。

通过这种方式,我将能够为 field_a、field_b 值创建一个具有相同值但具有不同状态的新行。 但是在这个逻辑中有一个问题:如果我要删除一个已经删除的项目,我将违反约束唯一性。

例如:

  1. INSERT ("Element A" "XXX") -> 我将有:1,Element A,XXX,1 Status OK;
  2. 删除 1 -> 我将有:1,元素 A,XXX,1 个状态已删除;
  3. INSERT ("Element A" "XXX") -> 我将有:2, Element A, XXX, 1 Status OK;
  4. DELETE ("Element A" "XXX") -> 我会报错,因为会违反唯一约束(Element A, XXX, 1 Status DELETED already exist);

是否可以有相同的约束,但是关于状态,我只想使用特定值(在这种情况下只能使用 OK)?

当一行的唯一索引表达式的任何组件等于 NULL 时,该行将被视为唯一的 anycase(因为一个 NULL 不等于另一个 NULL)。所以:

变体 1。status 列值使用 NULL 作为该行已删除的标记。

fiddle for variant 1

变体 2。 在索引表达式中使用将 DELETED 状态转换为 NULL 的表达式(如果您的服务器版本允许通过表达式进行索引):

CREATE UNIQUE INDEX idx
ON tablename (field_a, field_b, (CASE WHEN status = 'DELETED' THEN NULL ELSE status END))

fiddle for variant 2