тут он прав на все 100% — dml триггеры все-таки все-таки это зло, и применяются они только из компромисса, когда уже «слишком дорого и долго» переделывать изначальные архитектурные ошибки.
Можно пруф?
нормальное решение где одна процедура будет и обновлять остаток и вставлять записи в таблицу на паре десятков конкурентных процессов в несколько тысяч вставок
Весь вопрос как эта процедура будет обновлять остаток. Если пересчитывать select sum() from table, то это будет долго на больших объёмах. Если обновлять set total = total + current_amount, то на нескольких конкурентных процессах вы в любом случае наткнётесь либо на блокировки, либо на некорректные итоги.
А вдруг вы там с рестартами по 3 раза некоторые операции снижения баланса понапроводили?
Здесь и здесь. Помните условия решаемой задачи? Обновлять представление во время каждого коммита слишком накладно. Если не обновлять — теряем целостность.
Полностью согласен с вами.
Конечно, в реальности триггер несколько развесистее, с контролями и обработкой разных ситуаций. Я сознательно привёл только участок кода, на оптимизацию которого обращаю внимание в статье.
Опять же, призываю всех включать своё инженерное мышление. Воможно, в каких-то конкретных случаях есть смысл ради повышения производительности упростить триггерную функцию и запретить изменения, например, поля account в триггере BEFORE. В других случаях может быть принято решение пожертвовать скоростью операций вставки/изменения/удаления ради тотального контроля. А в каких-то случаях жертвуют целостностью ради повышения скорости вставки данных.
А задача топикстартера проще решается материализованной вьюшкой. То есть, в первом приближении, триггер или не нужен, или не применим.
Увы, не решается. Материализованное представление требует периодического обновления. При первой же записи в operations это представление будет содержать устаревшие данные до очередного обновления.
Ключевое слово — «временную». Временная таблица не может быть частью нормализованных данных. Ваша функция — часть бизнес логики, которая готовит срез данных на какой-то момент времени по запросу пользователя.
Если же вам нужно обеспечить, чтобы эта таблица ВСЕГДА содержала данные, соответствующие вашим операциям, тогда её можно и нужно рассматривать как часть ваших данных, к которым предъявляются требования к целостности.
Согласен с вами. За деталями однозначно — в оригинал.
Своей целью считаю по возможности более краткое изложение оригинала. Некоторые моменты типа 300*default_statistics_target посчитал излишней информацией. Думаю, что для начала достаточно знать, что есть параметр, при помощи которого моно управлять глубиной анализа. Если кому нужна конкретика — она есть в оригинале.
Использование транзакций не входит в тематику статьи. Полагаю, достаточно дать намёк на ROLLBACK. Возможно, напишу отдельную статью про использование транзакций при отладке.
Команду DELETE мне ни разу не приходилось отлаживать, в отличие от UPDATE.
В любом случае, за указание на неточности — спасибо. Подумаю, как лучше внести исправления.
Да, конечно, в продолжении будут более сложные вещи. Просто решил начать с самых основ, как в оригинале. Да не рассчитал с объёмом материала. Потому решил разделить на части.
Можно пруф?
Весь вопрос как эта процедура будет обновлять остаток. Если пересчитывать select sum() from table, то это будет долго на больших объёмах. Если обновлять set total = total + current_amount, то на нескольких конкурентных процессах вы в любом случае наткнётесь либо на блокировки, либо на некорректные итоги.
Рассчитываю, что буква A из ACID обеспечена.
Конечно, в реальности триггер несколько развесистее, с контролями и обработкой разных ситуаций. Я сознательно привёл только участок кода, на оптимизацию которого обращаю внимание в статье.
Опять же, призываю всех включать своё инженерное мышление. Воможно, в каких-то конкретных случаях есть смысл ради повышения производительности упростить триггерную функцию и запретить изменения, например, поля account в триггере BEFORE. В других случаях может быть принято решение пожертвовать скоростью операций вставки/изменения/удаления ради тотального контроля. А в каких-то случаях жертвуют целостностью ради повышения скорости вставки данных.
Увы, не решается. Материализованное представление требует периодического обновления. При первой же записи в operations это представление будет содержать устаревшие данные до очередного обновления.
Если же вам нужно обеспечить, чтобы эта таблица ВСЕГДА содержала данные, соответствующие вашим операциям, тогда её можно и нужно рассматривать как часть ваших данных, к которым предъявляются требования к целостности.
Знаю, что зануда, но всё-таки
Однозначно в избранное!
s/ключём/ключом/gБанки на верхней и нижней полках абсолютно одинаковые. Специально проверял.
Своей целью считаю по возможности более краткое изложение оригинала. Некоторые моменты типа
300*default_statistics_targetпосчитал излишней информацией. Думаю, что для начала достаточно знать, что есть параметр, при помощи которого моно управлять глубиной анализа. Если кому нужна конкретика — она есть в оригинале.Использование транзакций не входит в тематику статьи. Полагаю, достаточно дать намёк на ROLLBACK. Возможно, напишу отдельную статью про использование транзакций при отладке.
Команду DELETE мне ни разу не приходилось отлаживать, в отличие от UPDATE.
В любом случае, за указание на неточности — спасибо. Подумаю, как лучше внести исправления.