@footballer

Вопрос по статье на Хабре про триггеры — могут ли гарантировать триггеры целостность данных?

Вопрос по статье "Вы не любите триггеры?" https://habrahabr.ru/post/310040/

Там приводится пример "легкого" триггера:

update totals 
set total = totals.total + current_amount
where totals.account = current_account


Мне не очень понятно:
1) этот триггер, я так понимаю, повешен автором на событие AFTER INSERT таблицы operations. А current_amount - это кол-во, которое мы инсертим в таблицу operations. И автор внутри триггера цепляется к переменной current_amount, но как переменная current_amount попадет внутрь триггера? Или предполагается, что автор выше достал заинсерченную строку из таблицы inserted и присвоил в current_amount (то есть, автор просто опустил этот кусок кода)?

2) Делая триггер на вставку в таблицу operations, мы хотим, чтобы вспомогательная таблица totals обновлялась всегда, когда приложение шлет запрос на вставку в таблицу operations, так мы хотим обеспечить целостность. Но получается, что стороннее приложение по ошибке или по взлому может послать запрос на апдейт\вставку напрямую в таблицу totals, и тогда целостность данных все-равно нарушается. Т.к. таблица totals - вспомогательная, то мы должны разрешить вызывать инсерты\апдейты в эту таблицу только из нашего триггера (ну либо из процедур на стороне sql-сервера, и должны запретить делать там изменения запросами от сторонних приложений). Для этого нам нужно либо скрыть эту таблицу из схемы данных (чтобы она не была видна наружу, но была видна внутри sql-сервера), либо ограничить инсерты\апдейты (разрешив их только вызовами изнутри sql-сервера), но мне кажется, что sql-сервер не позволяет добавлять такие ограничения на таблицы (или я не прав?). Если я прав, то смысл нам писать триггер, обеспечивающий целостность, если хакерское приложение все-равно может нарушить целостность, вызвав напрямую апдейт\инсерт в таблицу totals?
  • Вопрос задан
  • 231 просмотр
Пригласить эксперта
Ответы на вопрос 3
Melkij
@Melkij
PostgreSQL DBA
но как переменная current_amount попадет внутрь триггера?

Автор статьи не стал вдаваться в детали какой-либо СУБД, поэтому уточняйте в документации к своей СУБД.
Для for each row триггеров обычно можно читать из NEW.amount в after insert триггерах.
Для for each statement - смотрите документацию к своей СУБД.

либо ограничить инсерты\апдейты (разрешив их только вызовами изнутри sql-сервера), но мне кажется, что sql-сервер не позволяет добавлять такие ограничения на таблицы

Смотрите опять же документацию к своей СУБД.
Для postgresql такую модель прав сделать можно. Для этого необходим отдельный пользователь для деплоя приложения (вообще полезная штука всегда) и security definer триггер.

могут ли гарантировать триггеры целостность данных?

Могут, но бывают сюрпризы. Например, mysql вам не запретит из триггера на ACID табличке что-то делать с myisam. Последующий rollback транзакции по любой причине = у вас потеря целостности. Впрочем, если вы знаете о целостности данных - то вы и не станете использовать всякое myisam.
Ответ написан
Комментировать
@DenisDangerous
А зачем для этого триггеры? Для обеспечения целостности существуют внешние ключи (Foreign Keys)
Ответ написан
@BorisKorobkov
Web developer
могут ли гарантировать триггеры целостность данных?

В зависимости от уровня изолированности транзакций.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы