Ограничение на число строк таблицы, соответствующих определенному условию, используя Postgres исключающее ограничение? - PullRequest
1 голос
/ 06 марта 2020

Если у меня есть схема Postgresql дБ для таблицы шин, подобной этой (у пользователя много шин):

user_id integer
description text
size integer
color text
created_at timestamp

, и я хочу применить ограничение, которое говорит, что «пользователь может иметь только 4 шины ".

Наивным способом реализации этого было бы сделать:

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

, сравнить результат с 4 и вставить, если он ниже 4. Он подвержен гоночным условиям и поэтому наивен подход.

Я не хочу добавлять столбец подсчета. Как я могу сделать это (или я могу сделать это), используя ограничение исключения? Если это невозможно с ограничениями исключения, каков канонический путь?

1 Ответ

0 голосов
/ 06 марта 2020

«Правильный» способ - использовать здесь замки. Во-первых, вам нужно заблокировать связанные строки. Во-вторых, вставьте новую запись, если у пользователя менее 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;

Подробнее вы можете прочитать здесь Как выполнить условную вставку на основе количества строк?

...