【问题标题】:Cap on number of table rows matching a certain condition using Postgres exclusion constraint?使用 Postgres 排除约束限制匹配特定条件的表行数?
【发布时间】:2020-03-05 22:03:07
【问题描述】:

如果我有一个类似这样的轮胎表的 Postgresql 数据库模式(用户有很多轮胎):

user_id integer
description text
size integer
color text
created_at timestamp

我想强制执行“用户只能有 4 个轮胎”的约束。

实现这一点的一种天真的方法是:

SELECT COUNT(*) FROM tires WHERE user_id='123'

,将结果与 4 进行比较,如果它低于 4,则插入。这可能是竞争条件,因此是一种幼稚的方法。

我不想添加计数列。我怎样才能使用排除约束来做到这一点(或者我可以做到这一点)?如果排除约束不可能,那么规范的方法是什么?

【问题讨论】:

    标签: postgresql exclusion-constraint


    【解决方案1】:

    “正确”的方式是在这里使用锁。 首先,您需要锁定相关行。其次,如果用户的轮胎少于 4 个,则插入新记录。这是 SQL:

    begin;
    
    -- lock rows
    select count(*)
    from tires
    where user_id = 123
    for update;
    
    -- throw an error of there are more than 3
    
    -- insert new row
    insert into tires (user_id, description)
    values (123, 'tire123');
    
    commit;
    

    您可以在这里阅读更多内容How to perform conditional insert based on row count?

    【讨论】:

    • 你写的东西里潜伏着一个正确的答案。 SELECT ... FOR UPDATE 应该在user_id 上,并且INSERT 中的重新检查是不必要的。
    猜你喜欢
    • 2015-04-17
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    相关资源
    最近更新 更多