Как лучше хранить остатки товаров поставщика: регистр сведений или документ без проведения?

Программист 1С v8.3 (Обычные формы) 1С:Комплексная автоматизация Управленческий учет Торговля и дистрибуция
← На главную

При интеграции с внешними поставщиками или складами ответственного хранения часто возникает задача регулярной загрузки снимков (снапшотов) товарных остатков. Формат входящих данных обычно прост: дата фиксации остатков, номенклатурная позиция и ее количество. Перед разработчиком встает дилемма проектирования структуры хранения: создать отдельный документ без проведения с табличной частью или использовать регистр сведений. Разберем по шагам архитектурные особенности обоих подходов, проанализируем влияние на производительность базы данных и выясним оптимальное решение.

Сравнение архитектуры: документ против регистра сведений

Рассмотрим, что происходит внутри реляционной базы данных (СУБД) при использовании документа без проведения:

  1. Хранение служебных данных: Табличная часть документа в СУБД представлена отдельной таблицей. Каждая строка содержит ссылку на документ-владелец (Ссылка), номер строки (НомерСтроки), а также реквизиты самой табличной части. Таким образом, аргумент об экономии места за счет выноса даты в шапку документа не выдерживает критики: ссылка типа УИД (16 байт) и номер строки занимают в каждой записи больше объема, чем стандартное поле типа Дата (8 байт).
  2. Индексация и выборка: В табличных частях документов по умолчанию нет кластерного индекса по полям номенклатуры. Кластерный индекс построен по связке Ссылка + НомерСтроки. Чтобы получить срез остатков или отфильтровать товар по истории в запросе, придется соединять таблицу документа с его шапкой для получения даты, а поиск по товару приведет к сканированию таблицы (Index Scan / Table Scan), если у реквизита номенклатуры явным образом не включено индексирование.
  3. Ограничения платформы: В табличных частях документов существует платформенное ограничение — не более 99 999 строк. Если номенклатурный прайс-лист или остатки внешнего склада превысят это число, запись документа завершится фатальной ошибкой.

Назначение документа в архитектуре 1С — это фиксация факта хозяйственной операции и формирование движений. Хранить периодические отчетные срезы в строках непроведенного документа является антипаттерном. Для хранения нормализованных срезов и состояний предназначен регистр сведений.

Особенности структуры регистра сведений для хранения остатков

Выясним, как правильно спроектировать регистр сведений под задачу загрузки полных снимков остатков на дату. Здесь есть два основных подхода:

  1. Периодический регистр сведений (периодичность — По позиции регистратора или День): Платформа автоматически добавляет поле Период в начало кластерного индекса. Если периодичность установлена в пределах дня, платформа гарантирует уникальность только одной записи на товар в течение суток. Однако стандартные виртуальные таблицы среза последних здесь могут работать не так, как ожидается: если товар был на остатке вчера, а сегодня в файле его нет (остаток стал равен нулю), срез последних без явной записи нулевого остатка продолжит возвращать вчерашнее значение.
  2. Непериодический регистр сведений с явным измерением типа Дата: Это наиболее гибкий вариант для загрузки плоских слепков данных. В качестве измерений используются: ДатаОстатков (тип Дата, состав «Дата»), Поставщик (при необходимости) и Номенклатура. Ресурсом выступает Количество. В таком регистре виртуальные таблицы срезов отсутствуют, а выборка остатка на нужную дату выполняется обычным прямым запросом с отбором по измерению даты, что гарантирует точное совпадение с загруженным файлом без наложения итогов за прошлые дни.

Проанализируем порядок измерений в регистре. В независимом регистре сведений кластерный индекс СУБД выстраивается строго в порядке следования измерений в дереве метаданных конфигуратора. Если первым измерением сделать ДатаОстатков, то поиск по номенклатуре без указания даты потребует сканирования всего индекса. Если наиболее частым сценарием является поиск остатков конкретного товара по всей хронологии, измерение Номенклатура должно предшествовать дате, либо для номенклатуры должно быть выставлено свойство «Индексировать».

Реализация пакетной записи остатков в регистр сведений

При ежедневной загрузке тысяч строк критически важно избегать построчной записи через РегистрСведенийМенеджерЗаписи. Одиночные записи создают избыточную нагрузку на транзакционный журнал СУБД и провоцируют блокировки.

Разберем пример эффективной записи данных через РегистрСведенийНаборЗаписей с предварительной очисткой данных за загружаемую дату:


НаборЗаписей = РегистрыСведений.ОстаткиТоваровПоставщиков.СоздатьНаборЗаписей();

// Устанавливаем жесткий отбор по границам перезаписываемых данных
НаборЗаписей.Отбор.ДатаОстатков.Установить(ТекущаяДатаОстатков);
НаборЗаписей.Отбор.Поставщик.Установить(ТекущийПоставщик);

// Заполняем набор записей из обработанной таблицы входящего XML
Для Каждого СтрДанных Из ТаблицаОстатков Цикл
    НоваяЗапись = НаборЗаписей.Добавить();
    НоваяЗапись.ДатаОстатков = ТекущаяДатаОстатков;
    НоваяЗапись.Поставщик    = ТекущийПоставщик;
    НоваяЗапись.Номенклатура = СтрДанных.Номенклатура;
    НоваяЗапись.Количество   = СтрДанных.Количество;
КонецЦикла;

// Записываем набор с замещением в рамках явной транзакции
НачатьТранзакцию();
Попытка
    НаборЗаписей.Записать(Истина);
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ЗаписьЖурналаРегистрации("Интеграция.Остатки", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
    ВызватьИсключение;
КонецПопытки;

Альтернативные подходы к оптимизации объема базы данных

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

  1. Двухуровневая схема (Срез + Архив): В регистре сведений хранятся исключительно актуальные остатки на текущий момент (перед каждой загрузкой регистр очищается). Если возникает необходимость расследовать расхождения прошлых периодов, исходные XML-файлы архивируются в сжатом виде в реквизит с типом ХранилищеЗначения служебного справочника или сохраняются на выделенном дисковом томе. Это исключает хранение миллионов тяжелых записей в индексированных реляционных таблицах.
  2. Регламентная очистка устаревших срезов (TTL): Если хранение срезов в регистре сведений необходимо для оперативной сверки за последний месяц, настраивается регламентное задание, которое удаляет наборы записей старше 30 или 60 дней, предотвращая бесконечный рост базы данных.
  3. Регистрация отклонений через регистр накопления: Если по остаткам поставщика требуется строить непрерывные отчеты, целесообразно загружать файл документом, который вычисляет разницу (дельту) между новым входящим количеством и текущим расчетным остатком, фиксируя только движения «Приход» или «Расход» в остаточном регистре накопления. Это позволяет задействовать стандартный механизм агрегатов и итогов платформы 1С.
← На главную