У меня есть проект клиента, который я сопровождал почти 2 года. На его примере интересно показать, как важно грамотно подходить к техническому решению задачи, чтобы потом не переделывать.
Проект был реализован в сети распределенных баз 1С. Суть его заключалась в том, чтобы не только в центре, но и на узлах можно было формировать некоторые отчеты, для расчета которых требовалось большое количество показателей по каждому товару. Причем эти показатели могли меняться с течением времени.
Клиент нарисовал матрицу, где по вертикали шли товары в виде иерархического дерева, в колонках стояли показатели. При вводе показателя в строке группы они автоматически назначались на все подгруппы и подэлементы.
Причем все узлы были разбиты на 3-5 групп показателей. Т.е. в каждой ячейке выводились показатели в столбик для каждой из групп показателей, чтобы была видна разница.
ЭТАП 1.
Первоначально задача была решена в лоб, без существенного анализа, даже не мной. Матрица на каждый месяц хранилась отдельной таблицей. На следующий месяц показатели копировались.
Недостатки решения:
1. На узлы генерировался большой поток данных. Загрузки на узлах шли по 20-40 минут.
2. Иногда нужно было внести изменения на прошлый период, приходилось дублировать их в новый период.
3. Показатели можно было вносить только на начало месяца.
4. Показатели занимали очень много места в базе узла, до 2-3 Гб из 5-7Гб. А для файловой базы объем - это критичное значение.
При выгрузке осуществлялась фильтрация, чтобы передавались только данные по группе показателей узла, чтобы не передавать лишние данные.
ЭТАП 2.
Было решено ввести историю и хранить только изменения показателей. Это решило проблему корректировки в предыдущих периодах и вступления показателей в действие с произвольной даты. Размер таблиц уменьшился, т.к. хранились только изменения. Однако возникла новая проблема - если происходил сбой обмена с узлом, приходилось выгружать всю таблицу. А она состояла из миллиона записей. Если в прошлом случае можно было выгрузить только показатели за месяц, то тут это не помогало. Когда размер таблицы вырос до критических объемов, пришлось как то решать проблему.
ЭТАП 3.
Алгоритмы отчета были написаны еще на первом этапе и использовали показатели на начало месяца. Показатели хранились не в отдельной таблице, а подставлялись запросом в отдельные колонки. Чтобы не сильно переделывать сложные расчеты отчета, в таблице операций происходила подмена показателей. Так работало некоторое время, но в итоге все же решились на рефакторинг, т.к. отдельная таблица показателей была более удобна, прозрачна и наглядна. По сути эти изменения никак не отразились для пользователей, но алгоритм стал проще.
ЭТАП 4.
Отказались от передачи в узлы таблицы показателей целиком. На узел передавалась таблица показателей за каждый месяц, сжатая в хранилище значений с максимальной степенью сжатия, занимающая 100-200 Кб. Каждое утро осуществлялся пересчет этих сжатых таблиц, если были изменения, они отправлялись на узлы. Решение оказалось оптимальным. Причем таблица была расчитана именно для данного узла, т.е. можно было использовать более тонкие настройки, завязанные не на отдельные группы показателей, а на отдельные точки.
Также была создана процедура очистки, которая удаляла на узле старые таблицы. Это уменьшило объем баз.
ИТОГИ.
Указанный пример показывает, как важно учитывать все факторы при решении задачи.
Видно, что здесь важными факторами оказались:
1. Период действия показателей (начало месяца - произвольная дата)
2. Доставка показателей в узлы к потребителям
3. Размеры показателей для хранения в узлах, их очистка.
Рассматривался также вариант, когда узел передает запрос в центр, а уже там формируется отчет. Тогда вообще не нужно было бы передавать показатели в узел. Но страдала бы оперативность - т.к. в центре нет данных от узла по состоянию именно на текущий момент времени. Нужно было бы передавать изменения, произошедшие на узле, за последние 2-3 дня (для верности), важные для отчета. Если бы изначально задуматься о решении, то можно было бы использовать этот подход. Но уже поздно переделывать, так что остановились на разумном компромиссе.
Journal information