Хранимые агрегаты

WGA
Дата: 19.04.2017 11:44:37
Всем привет!

Такая тема. Появилась тут задача по бухгалтерскому учету. Храним проводки, требуются отчеты. Самые обычные: ОСВ, задолженности по договорам и т.п. Аналитики предлагают помимо таблицы с проводками несколько доп. таблиц с хранимыми агрегатами: обороты по счетам, обороты в разрезе аналитик, обороты в корреспонденции счетов. Вроде вещь стандартная, чтобы не считать по проводкам.

Все бы ничего, да только предлагается поддерживать хранимые агрегаты актуальными онлайн, т.е. создаем проводки и в той же транзакции обновить хранимые агрегаты. Учет многофилиальный и чтобы поддерживать целостность данных, требуется накладывать блокировки по филиалу. Я такого прежде не видел, честно говоря... Обычно пересчитывали ночью или по закрытию отчетного периода.

Скажите, пжл, в учетных системах это действительно принятая норма? Мне как-то страшновато выстраивать такие очереди
LSV
Дата: 19.04.2017 11:56:41
Никаких норм не существует. Есть просто требования бизнеса.
Но нужно четко отделять "блажь бухов" и "обоснованные требования".
Обычно ночных пересчетов достаточно. Также можно иметь под рукой обработку на пересчет какого-то конкретного контрагента, если нужно получить инфу срочно.
s_ustinov
Дата: 19.04.2017 11:59:18
WGA
Скажите, пжл, в учетных системах это действительно принятая норма? Мне как-то страшновато выстраивать такие очереди

Большинство систем писалось давно. Поэтому люди извращались как могли.

Сейчас многое поменялось, и "аналитиков", предлагающих такие решения, надо гнать ссаными тряпками.

Читаем про материализованные представления (в MS SQL называются индексированные представления). Да и вообще читаем про индексы.
WGA
Дата: 19.04.2017 12:28:35
s_ustinov
Читаем про материализованные представления (в MS SQL называются индексированные представления). Да и вообще читаем про индексы.
Про материализованные представления в курсе.
С оптимизацией SQL-запросов тоже знаком не понаслышке. Хотя индексы слабо помогают при расчете того же начального сальдо. Хоть кластеризованные (MSSQL), хоть какие.

Основной аргумент в пользу описанного подхода - преобладать будут операции на чтение. И хочется хранить данные уже подготовленными. У меня контраргумент: очень дорогая вставка проводок. По прикидками, создание одной проводки приводит к необходимости вставить/обновить от 50 строк (а может и больше) в таблицах хранимых агрегатов. Как-то слишком затратной становится. Какие еще аргументы можно привести против?
WGA
Дата: 19.04.2017 12:44:42
s_ustinov
Читаем про материализованные представления (в MS SQL называются индексированные представления). Да и вообще читаем про индексы.
Кстати, используется PostgreSQL.Там мат.вьюхи требуется пересчитывать, они не онлайн.
s_ustinov
Дата: 19.04.2017 17:09:50
WGA
s_ustinov
Читаем про материализованные представления (в MS SQL называются индексированные представления). Да и вообще читаем про индексы.
Кстати, используется PostgreSQL.Там мат.вьюхи требуется пересчитывать, они не онлайн.

И что, что не онлайн? Он что, при пересчете с нуля всё считает? Для подобных отчетов подождать секунду-две, пока СУБД пересчитает вьюшку - вполне нормально.

Главный аргумент против дополнительных табличек - потом тяжелее писать отчеты. Я как раз много отчетов разных написал, в том числе в финансах, и знаю, о чем говорю. Очень часто надо джойном данные из других мест подтянуть, и тогда эти предварительно рассчитанные итоги только мешают.
Еще такая схема может сильно просадить производительность.

Про аналитиков я серьезно. Если выдают такие рекомендации - они ламеры, а не аналитики.

Грубо, есть два варианта:
1. OLTP система с небольшим количеством данных (до нескольких миллионов фин проводок) и слабой нагрузкой. Просто пишем нормально запросы (+ делаем индексы) сразу в рабочей базе.
2. Система с более - менее приличной нагрузкой и данных от 10 миллионов. Ставим реплику базы для отчетов + делаем кубы и прочие навороты. Но в самой рабочей базе специально для целей отчетов всё равно ничего не делаем.

Пытаться в рабочей OLTP базе создавать структуры для отчетов и апдейтить их в транзакциях. "Дебилы, б..." (© Министр иностранных дел Российской Федерации)
leonmbs
Дата: 19.04.2017 17:29:12
полный пересчет вполне реален на современных мощных серверах - железо нынче копейки стоит. Особенно если все суммы хранить в копейках чтобы считало по целому типу

полный пересчет имеет важные преимущества - например не надо хранить промежуточные остатки и элементарно реализовывются проводки задним числом. Обороты тоже легко высчитываются - та же сумма только за период а не с нуля.
Что касается аналитики то при грамотном подъходе (не дуьбблируя тупо субконто из 1С) вполне можно обойтись одной таблицей синтетических счетов и связаной с ней одной таблицей агрегатов.
WGA
Дата: 19.04.2017 18:50:17
s_ustinov,

Хотел я аналитикам скинуть ссылку на этот топик, но после Ваших комментариев, пожалуй, воздержусь )) Мне тоже не нравится все это...
s_ustinov
Дата: 19.04.2017 20:10:20
WGA
Хотел я аналитикам скинуть ссылку на этот топик, но после Ваших комментариев, пожалуй, воздержусь )) Мне тоже не нравится все это...

Ну...
Согласен, министра иностранных дел не стоило цитировать.
Garya
Дата: 19.04.2017 23:43:53
WGA
Появилась тут задача по бухгалтерскому учету.
Как раз именно в бухгалтерском учете всё уже давным-давно придумано. Ведь понятие "бухгалтерской проводки" сводится к отражению хозяйственной операции на "бухгалтерских счетах", которые и являются, по своей сути, агрегатами. ОСВ - это всего лишь отчет, который выводит содержимое подобного агрегата в тех или иных аналитических разрезах.

Некоторые разработчики пытаются избежать хранения в базе отдельных сущностей вроде "бухгалтерских счетов" и "проводок" по ним, формируя, в частности, ОСВ непосредственно по массивам первичных документов в процессе формирования ОСВ как отчета. Однако, по-моему, это не совсем удачный подход по множеству причин.

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

Именно по этой причине первоисточники в виде электронных документов хранят в одних сущностях (журналах документов), а проводки, которые они вызывают, в других - в бухгалтерских счетах и бухгалтерских регистрах. Это удобно еще и потому, что неподготовленные по различным причинам документы огут оставаться "непроведенными", либо "проведенными частично" (например, когда по приходу ТМЦ предоставлена накладная ТОРГ-12, но не предоставлена корректно оформленная счет-фактура). Проводки также могут возникать не на основе формализованного документа с заранее расписанной схемой проводок, но и на основе "бухгалтерской справки", в которой могут быть совершенно любая заранее непредсказуемая совокупность проводок.

Таким образом, на счетах аккумулируется (агрегатируется) информация, у которой может быть огромное количество различных источников, алгоритмов и причин попадания на счета, в том числе несистематизируемые. ОСВ выводит отчет по этой информации, который никак слабо связан с источниками информации и который, как правило, не модифицируется при изменении схем проводок, алгоритмов проведения, появлении новых видов документов и т.п.

Бухгалтерский счет - и есть, по сути, нечто подобное OLAP-кубу. Аналитические разрезы бухгалтерского счета определяют перечень его измерений, учетные периоды - одно из измерений, другие определяются видом счета (для счетов взаиморасчетов это могут быть контрагенты и договоры, для счетов учета ТМЦ - перечень складов и номенклатура и т.д.). А суммы в различных валютах, натуральные показатели (количество) образуют его меры.

Понятно, что возникают взаимно противоположные задачи иметь максимально оперативно получаемые по проводкам агрегированные данные, и при этом не слишком утяжелять базу всеми комбинациями агрегатов и, по возможности, не слишком тормозить работу многих пользователей, которые проводят документы и оперативно отражают в учетной системе факты хозяйственной деятельности. Ну так это классическая задача оптимизации OLAP-куба. Можно хранить лишь часть агрегатов, а остальную досчитывать "на лету", когда она потребуется. Например, можно хранить остатки на начало каждого месяца и обороты за месяц по всей совокупности аналитических разрезов, а данные в промежутках между месяцами получать "на лету".

Классическая система имеет отдельные таблицы "документов" и "бухгалтерских счетов". "Проводки" - это формирование записей в таблицах "бухгалтерских счетов" на основе данных таблиц "документов". OLAP-кубы можно построить на таблицах счетов, исходя из фактических возможностей и требований к оперативности получаемых агрегатов.

P.S. А вообще-то это вопрос по тематике немного другого форума - разработка информационных систем.
Модератор: Могу перенести туда тему, если создатель темы не возражает