Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
Доброе утро всем. В учетной системе (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 не может поменяться, так как это уникальный счетчик, можете не говорить - это не так). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2005, 10:33 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
авторВопрос такой. Если дать такой запрос: 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 для _существующих_ строк и как то отловить эту ситуацию (при создании внешнего ключа отложенные проверки не использовались). Я думал, что база всегда находится в согласованном состоянии, а теперь возникает вопрос "как проверять целостность?" Думаю, нужно подождать комментария гуру. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2005, 13:29 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
я так подозреваю, что нужно создавать собственный constraint trigger вместо правила U8 и того триггера IDC_D, что создается автоматически при создании таблицы DOCUMENTS. Вот только команда create constraint trigger описана в доке достаточно обще. По такому описалову нихрена своего не создашь :-( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2005, 14:52 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
nostromoУдивительно, что в результате база данных приходит в несогласованное состояние: в таблице DOCUMENTS появляются записи, для которых нет соответствующих в таблице SCHEMES. В данном случае нарушение целостности при срабатывании руле - баг в чистом виде. Для руле постгресса этот баг - не единственный. ЗЫ. На мой взгляд - это - еще одно подтверждение никчемности реализации Руле-в в постгрессе. Причем реализаторы, кажется, вполне довольны идеологией своих рулей.. Убивать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2005, 15:39 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
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; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2005, 15:57 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
да. Я так делал в одном из случаев - вместо правила - триггер. Но тут же ж ситуация другая - надо, чтоб и update cascade проходил, и запрет на проведенные документы срабатывал. Вот и хочется - самому написать constraint trigger. Это нормально ? И где есть нормальное описание ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2005, 18:44 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
To strizh: Мне кажется самое простое решение для вашей задачи, это создать представление на таблицу DOCUMENTS, на неё навесить правило, запрещающее обновление проведенных документов и отдать её юзеру. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2005, 19:00 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.01.2005, 11:53 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
To assa: Если я создам запрещающий триггер вместо запрещающего правила, назову его так, чтобы он срабатывал позже каскадного constraint, то все равно вся транзакция откатится, если я верну ошибку из этого триггера. А как тогда запретить срабатывание запрещающего триггера, если уже сработал constraint ? Другими словами, можно ли сделать безусловный приоритет констрейнтов перед остальными триггерами ? to nostromo: подменить таблицу представлением - это хорошая идея. Только при этом надо в клиентском интерфейсе везде менять имя DOCUMENTS на DOCUMENTS_V. А этого никому делать не хочется. Да и судя по категоричности assa - рули все одно кривые, и их надо бы избегать. У меня идея была поступить по-простому. В запрещающем триггере проверять еще и имя юзера. И если это владелец базы - то только ему позволять все обновления (в том числе которые по update cascade идут), в том числе проведенных документов. Но это ж тогда юзерам неудобно. Кто-то схему поменял (у меня в базе еще несколько таких мест есть - артикулы шведского производителя, к примеру, которые изредка меняются по присылаемой оттуда таблице соответствия) - а бежать менять надо к админу - бо только он сможет. Неправильно это как-то. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.01.2005, 15:25 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
strizh подменить таблицу представлением - это хорошая идея. Только при этом надо в клиентском интерфейсе везде менять имя DOCUMENTS на DOCUMENTS_V. А этого никому делать не хочется. Да и судя по категоричности assa - рули все одно кривые, и их надо бы избегать. Можно не переделывать клиентские приложения, если данные перенести в новую таблицу DOCUMENTS_DATA, а представление на эту таблицу назвать DOCUMENTS. Что касается RULE, то вместо него можно использовать триггер. Это непринципиально. автор У меня идея была поступить по-простому. В запрещающем триггере проверять еще и имя юзера. И если это владелец базы - то только ему позволять все обновления (в том числе которые по update cascade идут), в том числе проведенных документов. Но это ж тогда юзерам неудобно. Кто-то схему поменял (у меня в базе еще несколько таких мест есть - артикулы шведского производителя, к примеру, которые изредка меняются по присылаемой оттуда таблице соответствия) - а бежать менять надо к админу - бо только он сможет. Неправильно это как-то. Кажется, это называется Row-Level Security (RLS). Есть статья по этому поводу. Для Постгреса стандартных стредств нет, обычно проблему решают с помощью создания представлений и раздачей прав на них. RLS просто позволяет избежать лишних хлопот (представления нужно как-то называть, вручную раздавать права, и если пользователей много, то это неудобно). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.01.2005, 16:20 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
Да, про RLS интересная статейка. У меня в базах анализ весь разрозненный. Где на триггерах, где на view, где на рулях. И по понятным юзерам полям. А тут идея с полем ACL мне понравилась. 0) выбрасываем все имевшиеся средства защиты 1) на каждую таблицу добавляем поле ACL 2) на каждую таблицу вешаем after update trigger с заполнением ACL по неким таблицам корпоративной политики безопасности (о, у меня уже таблица ролей юзеров есть :) ) 3) на каждую таблицу вешаем before update or delete trigger с проверкой поля ACL (только надо эффективно вычислять эту самую проверку) 4) на каждую таблицу вешаем before select rule с такой же проверкой. Все - унифицированная RLS для любых баз на pgsql. Пора встраивать универсальный механизм в будущие версии сервера :) Осталось только подумать над этими-самыми таблицами описания политик и функцией (функциями) проверки :-). А кстати. Где-то можно внятно почитать про не так давно появившиеся группы, схемы, домены ? Для чего конкретно и как практически их применять в целях совершенствования администрируемости, безопасности и пр. ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.01.2005, 20:17 |
|
||
|
одновременное применение правил, запрещающих изменения, и констрейнтов с on update cascade
|
|||
|---|---|---|---|
|
#18+
А вот когда ты оценишь быстродействие этих идей реализованных на plpgsql, сразу драгие мысли полезут... у нас уже как полгода эту мазу обсасываем со всех сторон (до статьи еще, и ближе уже к практической реализации чем автор, который только теорию развел - ее в каждой книге полно)- плохо все , если не на C++, громоздко и неуклюже... Вот сделаем - похвастаюсь =)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 20:53 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=32883349&tid=2007488]: |
0ms |
get settings: |
5ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
45ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 245ms |
| total: | 365ms |

| 0 / 0 |
