вопрос новичка. Триггер или представление или... как правильно?

boatswainn
Дата: 29.01.2013 15:18:33
Сразу прошу прощения за глупый вопрос :) ...

Сформулирую на примере:
есть таблица1: ФИО, сумма, дата транзакции.
часто нужно знать общую сумму по ФИО (назовем это балансом), и использовать это значение в других расчетах.

как правильно это сделать:
1. через триггер? т.е. создать таблицу2: ФИО, баланс ; и при каждом insert'е в таблицу1 изменять (сложением) соответствующую ячейку баланс таблицы2 ?

2. использовать представление (select) view2: ФИО, баланс ; в котором буду группировать по ФИО с суммированием значений сумм из таблицы1.

3. ?..
artas
Дата: 29.01.2013 15:23:09
boatswainn,
на ходу просчитывать не вариант ?
select sum(sum) from table where fio = 'fio' group by fio
boatswainn
Дата: 29.01.2013 15:30:06
так вот же и не знаю :)
база предполагается большая. что вьюха, что "на лету" select'ом будет каждый раз бегать по всей таблице1 и считать. а триггер - только когда будут добавляться новые транзакции...
вот и интересно, как обычно люди делают. как правильно, оптимально ? :)
вадя
Дата: 29.01.2013 15:31:26
расчитываемые значения не стоит хранить (за исключением случаев когда расчет/суммировани занимает очень много времени)
функции достачточно для получения результата - на входе id записи (для требуемого ФИО) , на выходе требуемая величина
проще не бывает. суммирование - агрегатная функция в пользовательской финкции (простите за тафталогию) требует мало ресурсов.

если хранить расчитываемую величину, то придется делать механизм контроля правильности сохраненной величины
и лавинообразного изменения при обнаружении не точности, что усложнит жизнь на порядки. и может уничтожить выйгрыш во времени.
Akina
Дата: 29.01.2013 15:32:57
1. Крайне осторожно. Триггеры срабатывают не на любой чих - можно огрести лажу в таблице итогов. Нужно строго контролировать, что нет операций, которые изменяют данные, но не вызывают срабатывания триггера.
2. Неразумно. Вьюв всегда материализуется, потому обычно проигрывает рантайм-подзапросу - особенно если используется фильтрация.
3. artas имхо прав - считай, когда потребовалось, и только для тех, для кого нужно.
вадя
Дата: 29.01.2013 15:34:42
select sum(sum) from table where fio = 'fio' group by fio


искать так
where fio = 'fio'
абсолютно не верно, а советовать тем более
для этих случаев есть айдишники....
вадя
Дата: 29.01.2013 15:38:29
автор
Вьюв всегда материализуется, потому обычно проигрывает рантайм-подзапросу - особенно если используется фильтрация.


правильное замечание
нужно выбирать по месту: удобство и наглядность vs скорость
boatswainn
Дата: 29.01.2013 15:43:12
Всем спасибо.

вадя
искать так
where fio = 'fio'
абсолютно не верно, а советовать тем более
для этих случаев есть айдишники....


это все понятно :) я для примера взял простую таблицу без нормализции. меня сам подход интересует...

вадя
если хранить расчитываемую величину, то придется делать механизм контроля правильности сохраненной величины
и лавинообразного изменения при обнаружении не точности

а можете подробней это объяснить ?



т.е. я правильно понимаю, что обычно для этого используют функции (или считают "на лету"), и каждый раз проходят по всей таблице с транзакциями ? а если она (эта таблица) огромна ??
вадя
Дата: 29.01.2013 16:09:39
что значит огромна?
проверь.

у тебя 100 000 записей
у тебя возникли сомнения в достоверности,
1 как будешь искать?
2 как будешь исправлять? если сохраненное расчитываемое значение используется еще где-то? представляешь сколько изменений надо внести?

хотя 1с хранит расчетное за периоды, для ускорения текущих значений. но у них и механизм защиты сохраненных - тоже не маленький.

в первом случае (при расчете) ошибки только от ввода не правильного (контроль исправления это отдельно - права и прочее)
во-втором - плюс ошибки от "неправльных проводок" , которые могу всплыть в будущем. не все варианты сможешь смоделирорваь в процессе отладки.

считвть на лету - с индексированными полями не долго.
boatswainn
Дата: 29.01.2013 17:17:16
вадя, спасибо! %)

и тогда еще один вопрос. скажем через год я захочу "заархивировать" таблицу1 с сохранением данных о накопленном балансе. правильно ли я понимаю, как это сделать (не меня кода скриптов):

таблица1 переименовывается в таблица2. Создается новая таблица1 такой же структуры. Единожды считаю балансы теперь уже по таблице2 и делаю insert в таблицу1. Старые скрипты все так же работают с таблицей1, но балансы уже учтены.

или может есть какие штатные механизмы для этих целей ?