powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Семь синих
13 сообщений из 13, страница 1 из 1
Семь синих
    #39664281
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задачка.
Как это сделать средствами Постгреса?
Сделать таблицу и навесить средствами Постгреса что нужно, чтобы в таблице могли храниться некие записи с атрибутом цвет и чтобы в таблицу можно было вписать не более семи синих.
С другой стороны - найти прокол в этом решении, какими последовательностями команд (с какого psql если их несколько) можно вписать восьмой синий.
...
Рейтинг: 0 / 0
Семь синих
    #39664289
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Этот поток сознания расшифровывается как-то?
...
Рейтинг: 0 / 0
Семь синих
    #39664290
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну я,

Гугл в помощь :-)

https://postgrespro.ru/docs/postgrespro/10/datatype-enum
...
Рейтинг: 0 / 0
Семь синих
    #39664329
vsl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
vsl
Гость
mad_nazgul,

enum тут ни при чём. Человек хочет constraint, ограничивающий количество строк в таблице.


ну я,

только триггеры. on before insert or update. Что-то похожее описано тут — в таблицу добавлена служебная колонка с CHECK-constraint, которая заполняется в триггере.

Чтобы не добавлять лишнюю колонку — можно выбрасывать ошибку сразу из триггера.

Чтобы «вписать восьмой синий», достаточно будет [временно] отключить триггер.
...
Рейтинг: 0 / 0
Семь синих
    #39664333
PgSQLanonymous3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну яЗадачка.
Как это сделать средствами Постгреса?
Сделать таблицу и навесить средствами Постгреса что нужно, чтобы в таблице могли храниться некие записи с атрибутом цвет и чтобы в таблицу можно было вписать не более семи синих.
Так, что ли?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
CREATE SCHEMA myschema;
SET search_path = 'myschema';

CREATE TABLE items_with_colors(
item_id serial PRIMARY KEY,
color text NOT NULL
);

CREATE OR REPLACE FUNCTION check_too_many_blue() RETURNS TRIGGER
AS $func$
DECLARE
cnt bigint;
BEGIN
IF (pg_catalog.current_setting('transaction_isolation') <> 'serializable') THEN
   RAISE EXCEPTION 'This database must be used in transaction isolation level SERIALIZABLE!';
END IF;
SELECT COUNT(*) INTO cnt
  FROM items_with_colors
 WHERE color = 'blue';
IF cnt > 7 THEN
   RAISE EXCEPTION 'Too many blue records!';
END IF;
RETURN NULL;
END;
$func$ LANGUAGE plpgsql SET search_path FROM CURRENT;

CREATE TRIGGER check_too_many_blue
 AFTER INSERT OR UPDATE ON items_with_colors
   FOR EACH STATEMENT EXECUTE PROCEDURE check_too_many_blue();



ну яС другой стороны - найти прокол в этом решении, какими последовательностями команд (с какого psql если их несколько) можно вписать восьмой синий.
Отключить триггер, любым способом (быть owner или superuser, например).
...
Рейтинг: 0 / 0
Семь синих
    #39664394
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PgSQLanonymous3,

В базе лежит 6 синих записей. Два процесса видят, что можно добавить. Берут и вставляют по одной своей. Получаем 8.
...
Рейтинг: 0 / 0
Семь синих
    #39664412
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну яPgSQLanonymous3,

В базе лежит 6 синих записей. Два процесса видят, что можно добавить. Берут и вставляют по одной своей. Получаем 8.

При уровне изоляции serializable один из них вылетит с ошибкой сериализации.

--
Maxim Boguk
dataegret.ru
...
Рейтинг: 0 / 0
Семь синих
    #39664416
PgSQLanonymous3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну яPgSQLanonymous3,
В базе лежит 6 синих записей. Два процесса видят, что можно добавить. Берут и вставляют по одной своей. Получаем 8.
Если Вам это каким-то подобным образом удастся с приведённым мной триггером, можете смело писать bug report в проект PostgreSQL.
...
Рейтинг: 0 / 0
Семь синих
    #39664422
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PgSQLanonymous3ну яPgSQLanonymous3,
В базе лежит 6 синих записей. Два процесса видят, что можно добавить. Берут и вставляют по одной своей. Получаем 8.
Если Вам это каким-то подобным образом удастся с приведённым мной триггером, можете смело писать bug report в проект PostgreSQL.

Я бы кстати забил бы на serializable уровень и сделать бы lock table items_with_colors в начале триггера просто или (что правильнее) advisory lock бы повесил для сериализации обработки триггеров.


--
Maxim Boguk
dataegret.ru
...
Рейтинг: 0 / 0
Семь синих
    #39664441
PgSQLanonymous3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim BogukЯ бы кстати забил бы на serializable уровень
А с какой целью Вы бы это сделали, если не секрет?
Перерешить (и, возможно, не решить) решённую задачу?

Maxim Boguk и сделать бы lock table items_with_colors в начале триггера просто
Зачем? Сериализовать вставку, даже если это не нужно (могут же не только синие вставляться)?

Maxim Bogukили (что правильнее) advisory lock бы повесил для сериализации обработки триггеров.
Чтобы создать систему костылей и подпорок?
Т.е. потом как-то распределять пространство advisory locks между подобными триггерами (которые могут быть на многих таблицах) и прочими возможными функциями, которые их используют? ;)
...
Рейтинг: 0 / 0
Семь синих
    #39664444
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PgSQLanonymous3,

Чтобы не заставлять вставку делать только через serializable (что далеко не всегда реально если нет возможности поправить вызывающее вставку приложение или по каким то причинам это делать не желательно).
Т.е. чтобы не требовалась модификация работающего с таблицей кода.

--
Maxim Boguk
dataegret.ru
...
Рейтинг: 0 / 0
Семь синих
    #39664446
Фотография vyegorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну я,

Для решения надо делать очередь. Как — это на усмотрение, мне приходит в голову:
1. создать таблицу с цветами и делать SELECT FOR UPDATE цвету, чтобы никто другой не мог вставить такой цвет в параллель.
2. рекомендательные блокировки, также можно по ID цвета во вспомогательной таблице или по константе
3. SERIALIZABLE: сначала проверяем, потом вставляем
4. Триггер
5. Блокировать таблицу целиком
...
Рейтинг: 0 / 0
Семь синих
    #39665500
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vyegorovну я,

Для решения надо делать очередь. Как — это на усмотрение, мне приходит в голову:
1. создать таблицу с цветами и делать SELECT FOR UPDATE цвету, чтобы никто другой не мог вставить такой цвет в параллель.
2. рекомендательные блокировки, также можно по ID цвета во вспомогательной таблице или по константе
3. SERIALIZABLE: сначала проверяем, потом вставляем
4. Триггер
5. Блокировать таблицу целиком
Сенкс, стало понятнее.
Еще вопрос про откат транзакции. Типа процесс удалил синий, второй вставил, первый роллбек. Я правильно понимаю, что второй в постгресе не увидит удаления?
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Семь синих
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]