首页 > 解决方案 > 如果第三列为真,则确保两列的唯一性

问题描述

| row (int)     | thingy_a_id (int)     | thingy_b_id (int)     | bool  | bunch_more_cols   |
|-----------    |-------------------    |-------------------    |------ |-----------------  |
| 1             | 6                     | 2                     | 0     |                   |
| 2             | 3                     | 3                     | 0     |                   |
| 3             | 2                     | 4                     | 0     |                   |
| 4             | 2                     | 4                     | 0     |                   |
| 5             | 2                     | 4                     | 1     |                   |
| 6             | 6                     | 2                     | 0     |                   |

在我正在创建的数据库中,我需要两列的组合才能唯一,但只有当第三列为真时。因此,在上面的示例中,第 3 行和第 4 行具有相同的 a 和 b 列是可以的,因为 bool 为 False (0)。并且第 5 行具有与 3 和 4 相同的 a 和 b 列也是可以的,因为它是唯一一个 bool 为真的 (1)。而且,如果在 thingy_a_id 为 2、thingy_b_id 为 4 且 bool 为 False (0) 的情况下又提交了另一行,那就没问题了。

我需要防止的是另一行被提交,其中 thingy_a_id 为 2,thingy_b_id 为 4 并且 bool 为 True (1)。

这可以用mySql完成吗?我怎么能做到这一点?

标签: mysqlsqlunique-constraint

解决方案


就目前而言,MySQL 不支持部分唯一索引(与 Postgres 等其他数据库不同)。

解决此问题的一种方法是用 s 替换0inboolnull:如文档中所述索引允许可以包含的列的多个值UNIQUENULLNULL

因此,您首先要确保该列被声明为nullable,然后将所有0s 转换为null

update mytable set bool = null where bool = 0;

然后您可以创建唯一索引:

create unique index mytable_idx on mytable(thingy_a_id, thingy_b_id, bool);

有了这个设置,您可以放心,不会在(thingy_a_id, thingy_b_id)什么时候bool发生重复,并且在什么时候是1允许的。boolnull


推荐阅读