【问题标题】:Partial index in PostgresPostgres 中的部分索引
【发布时间】:2019-10-02 01:33:45
【问题描述】:

在我的一个项目中,我有一个表格,其中包含有关某种设备的固件更新的信息。最初,任何固件更新过程都处于 ENQUEUED 状态。更新过程可能有其他状态值,例如进行中、完成、失败。对于单个设备,可能存在状态为 COMPLETED 和 FAILED 的多行(已完成更新过程,最终状态!)。但在任何时候,对于处于 ENQUEUED 或 ONGOING 状态的每个设备都只能有 1 个更新过程 - 新固件的推出应该只适用于没有“活动/非最终”更新过程的设备。我试图用 Postgres 的部分索引来实现这个约束,但它没有像我预期的那样工作。

这是该表的简化版本:

CREATE TABLE firmware_update_processes
(
    id  uuid DEFAULT uuid_generate_v1(),
    device VARCHAR(10) NOT NULL,
    state VARCHAR (10) NOT NULL DEFAULT 'ENQUEUED',
    PRIMARY KEY (id)
);

这是唯一的部分索引:

CREATE UNIQUE INDEX unique_non_final_firmware_updates_processes
ON firmware_update_processes (device, state)
WHERE state IN ('ENQUEUED', 'ONGOING');

然后我验证了这个约束,但我仍然能够为给定设备插入多个“活动/非最终”更新过程...

INSERT INTO firmware_update_processes (device, state) VALUES ('device1', 'ENQUEUED');
INSERT INTO firmware_update_processes (device, state) VALUES ('device1', 'ONGOING');

是否有任何(可能是其他)方法可以在数据库级别完成此操作?任何帮助表示赞赏。

【问题讨论】:

    标签: postgresql constraints database-indexes


    【解决方案1】:

    我认为应该是:

    CREATE UNIQUE INDEX unique_non_final_firmware_updates_processes
    ON firmware_update_processes (device)
    WHERE state IN ('ENQUEUED', 'ONGOING');
    

    像您一样在 (device, state) 上有一个唯一索引,这将明确允许每个设备的 ENQUEUED 和 ONGOING 状态。使用仅在设备上的唯一索引,我们只允许每个设备处于 ENQUEUED 或 ONGOING 的一种状态。

    【讨论】:

      猜你喜欢
      • 2012-09-06
      • 2020-12-24
      • 1970-01-01
      • 2023-03-06
      • 2019-10-06
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 2022-08-16
      相关资源
      最近更新 更多