Баланс клиента: хранить или вычислять
От: merge  
Дата: 19.01.12 13:44
Оценка:
Вот есть у нак таблица Карты.
И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

Вот задался вопросом о получении баланса по карте.
Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?
Re: Баланс клиента: хранить или вычислять
От: fplab Россия http://fplab.h10.ru http://fplab.blogspot.com/
Дата: 19.01.12 13:51
Оценка:
Здравствуйте, merge, Вы писали:

M>Вот есть у нак таблица Карты.

M>И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

M>Вот задался вопросом о получении баланса по карте.

M>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?

Вычислять по операциям. В противном случае при удалении или изменении (в архиве) операции придется пересчитывать остатки по всем датам позже даты операции.
Приходиться заниматься гадостью — зарабатывать на жизнь честным трудом (Б.Шоу)
Re[2]: Баланс клиента: хранить или вычислять
От: Real 3L0 Россия http://prikhodko.blogspot.com
Дата: 19.01.12 14:05
Оценка:
Здравствуйте, fplab, Вы писали:

F>Вычислять по операциям. В противном случае при удалении или изменении (в архиве) операции придется пересчитывать остатки по всем датам позже даты операции.


А удалять/изменять разрешается?
Вселенная бесконечна как вширь, так и вглубь.
Re[2]: Баланс клиента: хранить или вычислять
От: Mamut Швеция http://dmitriid.com
Дата: 19.01.12 14:32
Оценка:
M>>Вот есть у нак таблица Карты.
M>>И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

M>>Вот задался вопросом о получении баланса по карте.

M>>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?

F>Вычислять по операциям. В противном случае при удалении или изменении (в архиве) операции придется пересчитывать остатки по всем датам позже даты операции.


Если поле одно, то можно использовать его в виде этакого кэша. Главное, не забыть его изменять вовремя


dmitriid.comGitHubLinkedIn
Re[3]: Баланс клиента: хранить или вычислять
От: merge  
Дата: 19.01.12 15:59
Оценка:
Здравствуйте, Mamut, Вы писали:

M>>>Вот есть у нак таблица Карты.

M>>>И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

M>>>Вот задался вопросом о получении баланса по карте.

M>>>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?

F>>Вычислять по операциям. В противном случае при удалении или изменении (в архиве) операции придется пересчитывать остатки по всем датам позже даты операции.


M>Если поле одно, то можно использовать его в виде этакого кэша. Главное, не забыть его изменять вовремя


я вот тоже к этому склоняюсь, чтобы не запускать сложный запрос на вычесление баланса.
только вот действительно, надо все места такие предусмотреть
Re: Баланс клиента: хранить или вычислять
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 19.01.12 16:09
Оценка: +2
Здравствуйте, merge, Вы писали:

M>Вот есть у нак таблица Карты.

M>И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

M>Вот задался вопросом о получении баланса по карте.

M>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?

Это всё сильно зависит от. Определяются параметры продуктивной системы (сколько клиентов, транзакций и т.п) и делается нагрузочное тестирование. Если программа ещё только пишется, то можно написать прототип. Смотрим, выдерживает ли система нагрузки. Если выдерживает — оставляем динамическое вычисление (ибо нормализация, что есть благо). Если же не выдерживает — производим денормализацию. Причём, надо подумать как. Возможно, полезно будет обратить внимание на следующие моменты.

1. А вдруг завтра надо будет ещё считать баланс по клиентам? Или по месяцам? В этом случае лучше выносить такие вещи в отдельную таблицу.
2. Возможно, потребуется считать баланс на такую-то дату. Для этого можно хранить промежуточные балансы — за каждый день (на начало дня), месяц и т.п. Причём, бывает обычно такая штука, как "закрытие периода", что облегчает задачу — данные раньше определённой даты уже гарантированно не будут меняться. Это облегчит и вычисление актуально баланса, так что хранить его отдельно может и не придётся.

По-хорошему, операции не меняются и задним числом не делаются, а все ошибки сторнируются. Тогда вообще нет проблем с тем, чтобы пересчитывать данные при изменении существующих операций. В этом случае единственным основанием для изменения баланса будет появлении новой операции по карте.
Re[2]: Баланс клиента: хранить или вычислять
От: merge  
Дата: 19.01.12 16:40
Оценка:
Здравствуйте, konsoletyper, Вы писали:

т.е. вы предлагаете хранить слепки баланса по периодам (напр. формируется на суточной основе)?

K>Это всё сильно зависит от. Определяются параметры продуктивной системы (сколько клиентов, транзакций и т.п) и делается нагрузочное тестирование. Если программа ещё только пишется, то можно написать прототип. Смотрим, выдерживает ли система нагрузки. Если выдерживает — оставляем динамическое вычисление (ибо нормализация, что есть благо). Если же не выдерживает — производим денормализацию. Причём, надо подумать как. Возможно, полезно будет обратить внимание на следующие моменты.


K>1. А вдруг завтра надо будет ещё считать баланс по клиентам? Или по месяцам? В этом случае лучше выносить такие вещи в отдельную таблицу.

K>2. Возможно, потребуется считать баланс на такую-то дату. Для этого можно хранить промежуточные балансы — за каждый день (на начало дня), месяц и т.п. Причём, бывает обычно такая штука, как "закрытие периода", что облегчает задачу — данные раньше определённой даты уже гарантированно не будут меняться. Это облегчит и вычисление актуально баланса, так что хранить его отдельно может и не придётся.

K>По-хорошему, операции не меняются и задним числом не делаются, а все ошибки сторнируются. Тогда вообще нет проблем с тем, чтобы пересчитывать данные при изменении существующих операций. В этом случае единственным основанием для изменения баланса будет появлении новой операции по карте.
Re[3]: Баланс клиента: хранить или вычислять
От: fplab Россия http://fplab.h10.ru http://fplab.blogspot.com/
Дата: 20.01.12 04:24
Оценка:
Здравствуйте, Real 3L0, Вы писали:

R3>Здравствуйте, fplab, Вы писали:


F>>Вычислять по операциям. В противном случае при удалении или изменении (в архиве) операции придется пересчитывать остатки по всем датам позже даты операции.


R3>А удалять/изменять разрешается?


Это скорее вопрос к автору топика. Если удалять/изменять разрешается, то пересчет остатков может 1). занимать приличное время и 2). в случае сбоя в процессе пересчета остатков (ну там, к примеру, база глюкнула или еще что) остатки с вероятностью весьма близкой к 100% порвет. Выправить их можно либо ручками, либо опять же — пробегом по операциям и вычислением правильного остатка. А пересчет по операциям — чистое чтение, никаких DELETE/UPDATE.
Конечно, база должна быть нормализована. Поменьще стрингов, побольше интов.
Во известных мне банковских системах (кроме RS-Bank) остатки вычисляются по операциям. А в банках количество операций весьма не хилое На хорошо спроектированных и нормализованных таблицах это занимает очень небольшое время.
Приходиться заниматься гадостью — зарабатывать на жизнь честным трудом (Б.Шоу)
Re[3]: Баланс клиента: хранить или вычислять
От: konsoletyper Россия https://github.com/konsoletyper
Дата: 20.01.12 05:18
Оценка:
Здравствуйте, merge, Вы писали:

M>т.е. вы предлагаете хранить слепки баланса по периодам (напр. формируется на суточной основе)?


Нет, я всего лишь предлагаю рассмотреть различные варианты и привожу примеры.
Re: Баланс клиента: хранить или вычислять
От: icWasya  
Дата: 20.01.12 06:41
Оценка: :)
Здравствуйте, merge, Вы писали:

M>Вот есть у нак таблица Карты.

M>И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

M>Вот задался вопросом о получении баланса по карте.

M>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?

А вот банкомат (сбербанк) имеет две кнопки — 1)показать балланс и 2)показать несколько последних транзакций.
Первая выполняется бесплатно, вторая — за деньги.
Значит поле Балланс на счёте клиента всё таки есть.
Re: Баланс клиента: хранить или вычислять
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.01.12 14:39
Оценка:
Здравствуйте, merge, Вы писали:

M>Вот задался вопросом о получении баланса по карте.

M>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?
Мнение Владислава Чистякова: http://rsdn.ru/?article/db/RDBMS.xml
Автор(ы): Владислав Чистяков
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Баланс клиента: хранить или вычислять
От: fplab Россия http://fplab.h10.ru http://fplab.blogspot.com/
Дата: 23.01.12 07:30
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, merge, Вы писали:


M>>Вот задался вопросом о получении баланса по карте.

M>>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?
S>Мнение Владислава Чистякова: http://rsdn.ru/?article/db/RDBMS.xml
Автор(ы): Владислав Чистяков


Именно и вот еще одно мнение, подтверждающее, что не надо хранить всякую избыточную информацию, если это можно посчитать: "Дело в том, что хранить остатки и обороты совершенно не нужно. Их и так можно посчитать в любой момент времени."
Другое дело, что к вопросу надо подойти технически грамотно и В.Чистяков демонстрирует один из таких подходов
Приходиться заниматься гадостью — зарабатывать на жизнь честным трудом (Б.Шоу)
Re: Баланс клиента: хранить или вычислять
От: WMikhailov  
Дата: 28.01.12 12:46
Оценка: -1
Здравствуйте, merge, Вы писали:

M>Вот есть у нак таблица Карты.

M>И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

M>Вот задался вопросом о получении баланса по карте.

M>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?

Конечно, нужно хранить баланс клиента, а не вычислять его каждый раз. Для проверки корректности баланса существует таблица с операциями.
Причин несколько. Первой назову время получения баланса при подсчёте по операциям — с каждым разом оно будет расти. Вторая причина — как следствие первой — нагрузка на базу. Третья — обобщающая — представьте, что клиентов много..
Ну, и посмотрите на существующий удачный опыт (у сотовых операторов, у банков, у интернет-провайдеров) — баланс должен быть всегда доступен для клиента в его личном кабинете (а не скрыт) — ведь это _его_ деньги (и доверие конторе, и удобство, и т.д.)

P.S.: более того, если есть закрывающиеся периоды, то следует хранить и остатки на начало и конец периода. Как и сумму в рублях следует хранить, если при операции была конверсия, хотя и известна сумма в валюте и известен курс этой валюты. Вот так.
Re: Баланс клиента: хранить или вычислять
От: dimgel Россия https://github.com/dimgel
Дата: 29.01.12 11:53
Оценка:
Здравствуйте, merge, Вы писали:

M>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?


Одно другого не исключает. Настоятельно рекомендую вкурить древнюю идею "документы-регистры" в 1С-торговле. Балансы хранятся на момент "точка актуальности", пересчитываются при её сдвиге (кроме сдвига вперёд на одну проводку, где полный пересчёт не нужен). Т.е. текущий баланс может рассматриваться просто как кеш многомерной суммы по журналу операций. В том числе можно сделать его ленивым кешем, а также хранить ленивые промежуточные кеши (скажем, ежегодные, если в прошлых годах операции редкие).
Re[2]: Баланс клиента: хранить или вычислять
От: fplab Россия http://fplab.h10.ru http://fplab.blogspot.com/
Дата: 30.01.12 04:22
Оценка: +1
Здравствуйте, WMikhailov, Вы писали:

WM>Ну, и посмотрите на существующий удачный опыт (у сотовых операторов, у банков, у интернет-провайдеров) — баланс должен быть всегда доступен для клиента в его личном кабинете (а не скрыт) — ведь это _его_ деньги (и доверие конторе, и удобство, и т.д.)


Не скажу, как у сотовых операторов, а в известных мне банковских системах (за единственным известным исключением RS-Bank 5/5.5) баланс не хранится, а рассчитывается.
Понятие "доступности", вообще говоря, определено не строго. Клиенту, по большому счету до 3.1415926-ы, как именно он получает баланс: как сформированный по операциям, или как хранящийся в виде какого-то определенного, заранее рассчитанного, числа. Скорость получения этого числа определяется качеством ДНК программистов и администраторов БД. Кроме того, в последнем случае вам все равно никуда не деться от запросов к БД
Допустим, клиент пользовался своим пластиком 10 и 20 числа текущего месяца. Но он не обязан помнить точных дат совершения операций и поэтому вполне может запросить баланс по состоянию на 15 число. Но ведь данных на 15 число в БД нет. Понятно, что надо вернуть данные ближайшей меньшей даты, т.е. за 10-е. Для этого нужен дополнительный, не сложный, но все же SQL-запрос.
Не стоит плодить сущности сверх необходимого. Что можно не хранить — не храните. Все равно ведь есть таблица операций — вот по ней и вычисляйте баланс. При правильном подходе и грамотной реализации это занимает пустячное время.
Приходиться заниматься гадостью — зарабатывать на жизнь честным трудом (Б.Шоу)
Re[3]: Баланс клиента: хранить или вычислять
От: WMikhailov  
Дата: 01.02.12 14:35
Оценка:
Здравствуйте, fplab, Вы писали:

F>Здравствуйте, WMikhailov, Вы писали:


WM>>Ну, и посмотрите на существующий удачный опыт (у сотовых операторов, у банков, у интернет-провайдеров) — баланс должен быть всегда доступен для клиента в его личном кабинете (а не скрыт) — ведь это _его_ деньги (и доверие конторе, и удобство, и т.д.)


F>Не скажу, как у сотовых операторов, а в известных мне банковских системах (за единственным известным исключением RS-Bank 5/5.5) баланс не хранится, а рассчитывается.


Мой опыт работы говорит как раз об обратном.

F>Понятие "доступности", вообще говоря, определено не строго. Клиенту, по большому счету до 3.1415926-ы, как именно он получает баланс: как сформированный по операциям, или как хранящийся в виде какого-то определенного, заранее рассчитанного, числа. Скорость получения этого числа определяется качеством ДНК программистов и администраторов БД. Кроме того, в последнем случае вам все равно никуда не деться от запросов к БД


Конечно, даже по-малому клиенту всё равно, как получен актуальный (на данный момент) баланс — об этом я речи не велось. А речь о скорости получения информации клиентом.

От запросов к БД никуда не деться — тут Вы правы. Однако одно дело простой запрос одной строки с поиском из сотен тысяч записей по уникальному индексу, и совсем другое — агрегация набора записей с поиском из десятка миллионов записей по индексному интервалу. Напрасная нагрузка на БД.

F>Допустим, клиент пользовался своим пластиком 10 и 20 числа текущего месяца. Но он не обязан помнить точных дат совершения операций и поэтому вполне может запросить баланс по состоянию на 15 число. Но ведь данных на 15 число в БД нет. Понятно, что надо вернуть данные ближайшей меньшей даты, т.е. за 10-е. Для этого нужен дополнительный, не сложный, но все же SQL-запрос.


Речь велась об актуальном балансе (см. выше). Всё же выписка на дату редко интересует клиента (но в этом случае — да, без запроса не обойтись).

F>Не стоит плодить сущности сверх необходимого. Что можно не хранить — не храните. Все равно ведь есть таблица операций — вот по ней и вычисляйте баланс. При правильном подходе и грамотной реализации это занимает пустячное время.


Перефразирую: стОит иногда вводить сущности при необходимости. Здесь именно такой случай. Пожалейте БД — каждый клиент запрашивает баланс: на сотовом телефоне несколько раз в день, на банковской карточке — каждый раз при входе в личный кабинет. Заставлять SQL-машину поработать немного больше, чем она могла бы при такой простой процедуре — излишне.
Re: Баланс клиента: хранить или вычислять
От: wraithik Россия  
Дата: 02.02.12 18:19
Оценка: +1
Здравствуйте, merge, Вы писали:

M>Вот есть у нак таблица Карты.

M>И есть таблица ОперацииПоКартам, в которой есть дата и сумма операции

M>Вот задался вопросом о получении баланса по карте.

M>Как лучше? сделать поле Balance в таблице Карты и изменять его после каждой операции или же динамически вычеслять баланс на основании операций?

Как сделал 1С (в Навижине кажись так же).
Есть две таблицы: обороты (это твои операции) и остатки.
В остатках хранятся срезы, через фиксированный промежуток времени, например месяц.
Если ты пишешь запись задним числом, то соответственно пересчитываешь все итоги, стоящие после этой записи и связанные с ней по измерениям (в твоем случае это ID карты).
В результате итог по карте считается не по всем записям, а по оборотам последнего месяца и входящему остатку.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.