Периодический регистр сведений или непериодический с измерением даты: как правильно хранить остатки товаров поставщиков?

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

При проектировании механизмов загрузки прайс-листов и остатков сторонних контрагентов часто возникает архитектурная дилемма: использовать ли периодический регистр сведений с отключенными или неиспользуемыми срезами либо спроектировать непериодический регистр с отдельным измерением типа Дата. Разберем ключевые различия между этими подходами, проанализируем поведение СУБД, а также рассмотрим типовые практики платформы 1С:Предприятие 8.3.

Бизнес-логика: нужны ли срезы последних?

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

  1. Сегодня загружен файл с остатками поставщика: позиция «Товар 1» присутствует в количестве 10 штук.
  2. Завтра загружен обновленный файл поставщика: строка с позицией «Товар 1» полностью отсутствует.

Выясним, какое количество товара система должна считать доступным на текущий момент:

  1. Если ответ «0»: отсутствие товара в новой выгрузке означает его полное отсутствие на складе поставщика. В этом случае классическая логика среза последних («вернуть последнее известное значение за прошлый период») искажает реальность. Исторический срез здесь не требуется.
  2. Если ответ «10»: выгрузка отражает только изменения, а предыдущие остатки продолжают действовать до явной отмены. В такой ситуации механизм СрезПоследних необходим, и использование периодического регистра оправдано.

Внутреннее устройство индексов и поведение СУБД

Рассмотрим, как платформа 1С реализует структуры таблиц в реляционной СУБД в обоих случаях. Это принципиально важно для высоконагруженных баз с миллионами строк в прайс-листах.

Периодический регистр сведений:

В независимом периодическом регистре платформа принудительно создает как минимум два индекса:

  1. Кластерный первичный ключ: Измерение1 + ... + ИзмерениеN + Период.
  2. Дополнительный индекс: Период + Измерение1 + ... + ИзмерениеN.

Если для задачи не требуется выборка по хронологии всего среза данных, второй индекс будет расходовать дисковое пространство и замедлять операции массовой вставки (INSERT) при ежедневной загрузке сотен тысяч позиций.

Непериодический регистр с измерением даты:

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

Кроме того, стандартное поле Период всегда привязано к заданной периодичности регистра (Секунда, День, Месяц и т. д.) и округляется платформой автоматически. Собственное измерение типа Дата сохраняет переданную метку времени без платформенных модификаций.

Миф об отключении срезов в 1С 8.3

Разберем распространенное заблуждение относительно «отключения срезов». В платформе 1С:Предприятие 8.3 для периодических регистров сведений физические таблицы итогов срезов (свойства Разрешить итоги: срез последних и Разрешить итоги: срез первых) по умолчанию выключены. Это означает, что платформа не хранит предварительно рассчитанные срезы в отдельных таблицах СУБД.

Если эти свойства отключены, обращение к виртуальной таблице СрезПоследних в запросе формирует подзапрос с поиском максимальной даты MAX(Период) и соединением с основной таблицей. Поэтому «отключать» срезы для ускорения записи не требуется — дополнительных таблиц при настройках по умолчанию не создается.

Типовые архитектурные решения

Проанализируем, как аналогичные задачи решаются в типовых конфигурациях (например, в «1С:Управление торговлей 11») и на практике:

  1. Паттерн актуального среза (Snapshot):

    Если история изменения складских запасов поставщика за прошлые месяцы не нужна для сквозной аналитики, наиболее эффективным решением является непериодический регистр сведений без даты в ключе (измерения: Поставщик, Номенклатура; ресурсы: Количество, Цена; реквизиты: ДатаОбновления).

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

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

    Такой подход защищает базу данных от геометрического роста таблиц и предотвращает фрагментацию индексов.

  2. Периодический регистр для плановой доступности:

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

  3. Схема с регистром накопления:

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

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

← На главную