Как хранить табличную часть справочника в регистре сведений 1С, чтобы избежать реструктуризации?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Проанализируем ситуацию: у нас есть очень большой справочник, и для некоторых его элементов необходимо хранить списки дополнительных значений. Структура этих списков может меняться в будущем, что потребует новых реструктуризаций. Наша задача — найти гибкое решение, которое минимизирует простои системы.

Почему стандартная табличная часть может быть проблемой?

Основная причина, по которой разработчики ищут альтернативы, — это процесс реструктуризации таблиц в SQL. Когда вы добавляете новый реквизит или табличную часть в объект конфигурации 1С, платформа выполняет команду ALTER TABLE на уровне СУБД. На базах данных размером в сотни гигабайт или терабайты этот процесс может быть очень долгим.

Хотя в платформе 1С появился механизм отложенной реструктуризации (так называемая V2), он не всегда является панацеей. На очень больших базах данных даже этот механизм может выполняться часами, создавая значительную нагрузку на сервер. Если вы заранее знаете, что структура данных будет меняться, а новые данные нужны лишь для небольшой части элементов, имеет смысл рассмотреть хранение этих данных в отдельном регистре сведений.

Способ 1: Построчное хранение

Это самый очевидный и простой для понимания подход. Каждая строка вашей табличной части будет соответствовать одной записи в регистре сведений. Структура регистра в этом случае будет выглядеть так:

Преимущества:

Недостатки:

Способ 2: Хранение всей таблицы в ХранилищеЗначений

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

Структура регистра будет предельно простой:

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


// Пример записи данных
НоваяЗапись = РегистрыСведений.МоиДанныеТЧ.СоздатьМенеджерЗаписи();
НоваяЗапись.Объект = СсылкаНаЭлементСправочника;

// Создаем и заполняем таблицу значений
ТаблицаДляХранения = Новый ТаблицаЗначений;
ТаблицаДляХранения.Колонки.Добавить("Колонка1", Новый ОписаниеТипов("Строка"));
ТаблицаДляХранения.Колонки.Добавить("Колонка2", Новый ОписаниеТипов("Число"));

НоваяСтрока = ТаблицаДляХранения.Добавить();
НоваяСтрока.Колонка1 = "Значение 1";
НоваяСтрока.Колонка2 = 123;

// Помещаем таблицу в хранилище
НоваяЗапись.ДанныеТаблицы = Новый ХранилищеЗначений(ТаблицаДляХранения);

НоваяЗапись.Записать();

// Пример чтения данных
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
|   МоиДанныеТЧ.ДанныеТаблицы
|ИЗ
|   РегистрСведений.МоиДанныеТЧ КАК МоиДанныеТЧ
|ГДЕ
|   МоиДанныеТЧ.Объект = &Объект";
Запрос.УстановитьПараметр("Объект", СсылкаНаЭлементСправочника);

Результат = Запрос.Выполнить().Выбрать();
Если Результат.Следующий() Тогда
    // Извлекаем данные из хранилища
    ИзвлеченныеДанные = Результат.ДанныеТаблицы.Получить();
    Если ТипЗнч(ИзвлеченныеДанные) = Тип("ТаблицаЗначений") Тогда
        // работаем с таблицей
    КонецЕсли;
КонецЕсли;

Преимущества:

Недостатки:

Способ 3: Универсальная структура "Свойство-Значение" (EAV)

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

Такая структура регистра — наиболее гибкое и мощное решение для нашей задачи:

Как это работает: одна строка вашей виртуальной табличной части будет храниться в регистре как несколько записей. Например, строка `{Артикул: "Т001", Цена: 1500}` для объекта "Товар А" и `НомерСтроки = 1` будет представлена двумя записями в регистре:

  1. {Объект: "Товар А", НомерСтроки: 1, Реквизит: "Артикул", Значение: "Т001"}
  2. {Объект: "Товар А", НомерСтроки: 1, Реквизит: "Цена", Значение: 1500}

Преимущества:

Недостатки:

Итоги и рекомендации

Выбор способа хранения данных зависит от конкретной задачи. Давайте подведем итог:

  1. Если вам нужна простая структура, которая меняется очень редко, и важна легкость написания запросов — используйте построчное хранение.
  2. Если вам нужна абсолютная гибкость, а поиск по внутренним данным таблицы не требуется (например, вы просто храните какие-то конфигурационные данные) — идеальным вариантом будет ХранилищеЗначений.
  3. Если вам нужна высокая гибкость (структура будет меняться), но при этом необходима возможность поиска и отбора по данным — ваш выбор это универсальная структура "Свойство-Значение" (EAV), желательно с использованием Плана видов характеристик.

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

← На главную