如何在 Liquibase 中添加条件唯一约束?

How to add a conditional unique constraint in Liquibase?

问题:删除用户时,相关记录并未从数据库中删除。相反,我将 user.delete 列设置为 true。现在我需要对 user.email 设置唯一约束,但仅限于活跃用户(未删除)。

我该怎么做?

databaseChangeLog:
  - changeSet:
      id: add-user-unique-constraint
      author: me
      changes:
        - addUniqueConstraint:
            columnNames: email, delete
            constraintName: unique-email-not-deleted
            tableName: users

上述天真的方法对 (email, delete) 列施加了复合约束,但它不起作用,因为在以下流程中用户被阻止删除和创建帐户:

  1. 使用电子邮件注册新用户 "E"
  2. 删除电子邮件用户 "E"
  3. 用邮箱重新注册新用户"E"
  4. 删除电子邮件为 "E" 的用户 -> 错误:违反约束条件
  5. 使用电子邮件注册新用户 "E" -> 错误:违反约束条件

ps。数据库是 H2 和 PostgreSQL

此功能是特定于数据库的,目前 liquibase 不支持它。

对于 PostgreSQL 你可以直接使用 SQL:

databaseChangeLog:
  - changeSet:
      id: add-user-unique-constraint
      author: me
      changes:
        - sql:
            "sql": "CREATE UNIQUE INDEX user_email_idx ON user (email) WHERE delete = 'false'"

但是这 不会 H2 中工作。

H2的可能选项:

  • 如果它用于测试,那么您可以使用 testcontainers 技术迁移到 PostgreSQL(但您的构建环境将取决于 docker

  • 具有 PostgreSQLH2 的自定义变更集 - 您可以使用 preconditions