简体   繁体   English

使用 Postgres 排除约束限制匹配特定条件的表行数?

[英]Cap on number of table rows matching a certain condition using Postgres exclusion constraint?

If I have a Postgresql db schema for a tires table like this (a user has many tires):如果我有一个像这样的轮胎表的 Postgresql db 模式(用户有很多轮胎):

user_id integer
description text
size integer
color text
created_at timestamp

and I want to enforce a constraint that says "a user can only have 4 tires".我想强制执行一个约束条件,即“一个用户只能有 4 个轮胎”。

A naive way to implement this would be to do:实现这一点的一种天真的方法是:

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

, compare the result to 4 and insert if it's lower than 4. It's suspectible to race conditions and so is a naive approach. , 将结果与 4 进行比较,如果低于 4 则插入。这可能会导致竞争条件,因此是一种幼稚的方法。

I don't want to add a count column.我不想添加计数列。 How can I do this (or can I do this) using an exclusion constraint?我如何使用排除约束来做到这一点(或者我可以做到这一点)? If it's not possible with exclusion constraints, what is the canonical way?如果排除约束不可能,那么规范的方法是什么?

The "right" way is using locks here. “正确”的方法是在这里使用锁。 Firstly, you need to lock related rows.首先,您需要锁定相关行。 Secondly, insert new record if a user has less than 4 tires.其次,如果用户的轮胎少于 4 个,则插入新记录。 Here is the SQL:这是 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;

You can read more here How to perform conditional insert based on row count?您可以在此处阅读更多信息如何根据行数执行条件插入?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM