Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade / 12 сообщений из 12, страница 1 из 1
19.01.2005, 10:33
    #32871660
strizh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
Доброе утро всем.
В учетной системе (Postgres 7.4.6) есть таблица неких документов, у которой, среди прочих, есть вот так описанные поля:
... ID_SCH integer not null constraint IDC_D references SCHEMES(ID) on update cascade, REGISTERED bool not null default false ...
ID_SCH - идентификатор схемы операции, флажок REGISTERED - признак того, что документ проведен.
Есть правило, запрещающее внесение изменений в проведенные документы:
create rule U8 as on update to DOCUMENTS where old.REGISTERED do instead nothing;
Вопрос такой.
Если дать такой запрос:
update SCHEMES set ID = 99 where ID = 12;
то в проведенных документах ID_SCH изменится, или изменение в SCHEMES не пройдет, или в SCHEMES пройдет, но в документах только непроведенных ID_SCH изменится ?
От чего это зависит ? И может кто посоветует, как сделать правильно, чтобы все было логично - update cascade срабатывало для всех документов, но изменить проведенные документы оператором update DOCUMENTS было бы по-прежнему невозможно ? Что-то в правиле подправить ? Триггер написать ?
(про то, что ID не может поменяться, так как это уникальный счетчик, можете не говорить - это не так).
...
Рейтинг: 0 / 0
19.01.2005, 13:29
    #32872266
nostromo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
авторВопрос такой.
Если дать такой запрос:
update SCHEMES set ID = 99 where ID = 12;
то в проведенных документах ID_SCH изменится, или изменение в SCHEMES не пройдет, или в SCHEMES пройдет, но в документах только непроведенных ID_SCH изменится ?

Я не поленился и поставил эксперимент. Получается, что ID_SCH измениться только в непроведенных документах. Удивительно, что в результате база данных приходит в несогласованное состояние: в таблице DOCUMENTS появляются записи, для которых нет соответствующих в таблице SCHEMES. Если теперь удалить внешний ключ, то создать его снова не удастся. Если сделать backup то при восстановлении так же будут проблемы.
Если удалить правило, запрещающее update, то эти "плохие" строки все равно нельзя будет изменять, потому что происходит нарушение ограничения foregn key.
Плохо, что не удалось заставить postgres проверить выполнение foregn key для _существующих_ строк и как то отловить эту ситуацию (при создании внешнего ключа отложенные проверки не использовались). Я думал, что база всегда находится в согласованном состоянии, а теперь возникает вопрос "как проверять целостность?"

Думаю, нужно подождать комментария гуру.
...
Рейтинг: 0 / 0
19.01.2005, 14:52
    #32872508
strizh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
я так подозреваю, что нужно создавать собственный constraint trigger вместо правила U8 и того триггера IDC_D, что создается автоматически при создании таблицы DOCUMENTS. Вот только команда create constraint trigger описана в доке достаточно обще. По такому описалову нихрена своего не создашь :-(
...
Рейтинг: 0 / 0
19.01.2005, 15:39
    #32872688
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
nostromoУдивительно, что в результате база данных приходит в несогласованное состояние: в таблице DOCUMENTS появляются записи, для которых нет соответствующих в таблице SCHEMES.

В данном случае нарушение целостности при срабатывании руле - баг в чистом виде. Для руле постгресса этот баг - не единственный.



ЗЫ. На мой взгляд - это - еще одно подтверждение никчемности реализации Руле-в в постгрессе. Причем реализаторы, кажется, вполне довольны идеологией своих рулей.. Убивать.
...
Рейтинг: 0 / 0
19.01.2005, 15:57
    #32872743
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
strizhя так подозреваю, что нужно создавать собственный constraint trigger вместо правила U8 и того триггера IDC_D, что создается автоматически при создании таблицы DOCUMENTS. Вот только команда create constraint trigger описана в доке достаточно обще. По такому описалову нихрена своего не создашь :-(

Верните ошибку из обычных триггеров на апдейт и делете при OLD.REGISTERED = True. Она буит абортить транзакции. И делов.


Дока:This example will abort the transaction with the given error message:

RAISE EXCEPTION ''Inexistent ID --> %'', user_id;
...
Рейтинг: 0 / 0
19.01.2005, 18:44
    #32873255
strizh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
да. Я так делал в одном из случаев - вместо правила - триггер. Но тут же ж ситуация другая - надо, чтоб и update cascade проходил, и запрет на проведенные документы срабатывал. Вот и хочется - самому написать constraint trigger. Это нормально ? И где есть нормальное описание ?
...
Рейтинг: 0 / 0
19.01.2005, 19:00
    #32873278
nostromo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
To strizh:
Мне кажется самое простое решение для вашей задачи, это создать представление на таблицу DOCUMENTS, на неё навесить правило, запрещающее обновление проведенных документов и отдать её юзеру.
...
Рейтинг: 0 / 0
20.01.2005, 11:53
    #32874205
assa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
nostromoTo strizh:
Мне кажется самое простое решение для вашей задачи, это создать представление на таблицу DOCUMENTS, на неё навесить правило, запрещающее обновление проведенных документов и отдать её юзеру.

самое простое решение - избегать правил по возможности РУЛЕ - особенно если вы не знаете всех глюков этой фичи (или если собираетесь со временем переходить на более новые версии - поведение руле вероятно будет таки меняться - уж больно оно глючное.

авторНо тут же ж ситуация другая - надо, чтоб и update cascade проходил, и запрет на проведенные документы срабатывал.

Вы ничего не путаете? Каскад - это в постгресе, помнится, обычный триггер, висящий на мастере, но с функцией на Си. (Если каскадные форейгны подцеплены от мастера более чем на 1 таблицу - то будет висеть и срабатывать наколько таких триггеров. ) Т.ч. вот это должно работать:
ДОКАIf multiple triggers of the same kind are defined for the same event, they will be fired in alphabetical order by name.
...
Рейтинг: 0 / 0
20.01.2005, 15:25
    #32875046
strizh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
To assa:
Если я создам запрещающий триггер вместо запрещающего правила, назову его так, чтобы он срабатывал позже каскадного constraint, то все равно вся транзакция откатится, если я верну ошибку из этого триггера.
А как тогда запретить срабатывание запрещающего триггера, если уже сработал constraint ? Другими словами, можно ли сделать безусловный приоритет констрейнтов перед остальными триггерами ?

to nostromo:
подменить таблицу представлением - это хорошая идея. Только при этом надо в клиентском интерфейсе везде менять имя DOCUMENTS на DOCUMENTS_V. А этого никому делать не хочется. Да и судя по категоричности assa - рули все одно кривые, и их надо бы избегать.

У меня идея была поступить по-простому. В запрещающем триггере проверять еще и имя юзера. И если это владелец базы - то только ему позволять все обновления (в том числе которые по update cascade идут), в том числе проведенных документов. Но это ж тогда юзерам неудобно. Кто-то схему поменял (у меня в базе еще несколько таких мест есть - артикулы шведского производителя, к примеру, которые изредка меняются по присылаемой оттуда таблице соответствия) - а бежать менять надо к админу - бо только он сможет. Неправильно это как-то.
...
Рейтинг: 0 / 0
20.01.2005, 16:20
    #32875292
nostromo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
strizh
подменить таблицу представлением - это хорошая идея. Только при этом надо в клиентском интерфейсе везде менять имя DOCUMENTS на DOCUMENTS_V. А этого никому делать не хочется. Да и судя по категоричности assa - рули все одно кривые, и их надо бы избегать.


Можно не переделывать клиентские приложения, если данные перенести в новую таблицу DOCUMENTS_DATA, а представление на эту таблицу назвать DOCUMENTS. Что касается RULE, то вместо него можно использовать триггер. Это непринципиально.

автор
У меня идея была поступить по-простому. В запрещающем триггере проверять еще и имя юзера. И если это владелец базы - то только ему позволять все обновления (в том числе которые по update cascade идут), в том числе проведенных документов. Но это ж тогда юзерам неудобно. Кто-то схему поменял (у меня в базе еще несколько таких мест есть - артикулы шведского производителя, к примеру, которые изредка меняются по присылаемой оттуда таблице соответствия) - а бежать менять надо к админу - бо только он сможет. Неправильно это как-то.
Кажется, это называется Row-Level Security (RLS).
Есть статья по этому поводу. Для Постгреса стандартных стредств нет, обычно проблему решают с помощью создания представлений и раздачей прав на них. RLS просто позволяет избежать лишних хлопот (представления нужно как-то называть, вручную раздавать права, и если пользователей много, то это неудобно).
...
Рейтинг: 0 / 0
25.01.2005, 20:17
    #32883349
strizh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
Да, про RLS интересная статейка.
У меня в базах анализ весь разрозненный. Где на триггерах, где на view, где на рулях. И по понятным юзерам полям. А тут идея с полем ACL мне понравилась.
0) выбрасываем все имевшиеся средства защиты
1) на каждую таблицу добавляем поле ACL
2) на каждую таблицу вешаем after update trigger с заполнением ACL по неким таблицам корпоративной политики безопасности
(о, у меня уже таблица ролей юзеров есть :) )
3) на каждую таблицу вешаем before update or delete trigger с проверкой поля ACL (только надо эффективно вычислять эту самую проверку)
4) на каждую таблицу вешаем before select rule с такой же проверкой.

Все - унифицированная RLS для любых баз на pgsql. Пора встраивать универсальный механизм в будущие версии сервера :)

Осталось только подумать над этими-самыми таблицами описания политик и функцией (функциями) проверки :-).

А кстати. Где-то можно внятно почитать про не так давно появившиеся группы, схемы, домены ? Для чего конкретно и как практически их применять в целях совершенствования администрируемости, безопасности и пр. ?
...
Рейтинг: 0 / 0
26.01.2005, 20:53
    #32885787
centur
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
А вот когда ты оценишь быстродействие этих идей реализованных на plpgsql, сразу драгие мысли полезут... у нас уже как полгода эту мазу обсасываем со всех сторон (до статьи еще, и ближе уже к практической реализации чем автор, который только теорию развел - ее в каждой книге полно)- плохо все , если не на C++, громоздко и неуклюже...
Вот сделаем - похвастаюсь =))
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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