Как файловая база 1С хранит таблицы: построчно или поколоночно? Разбор архитектурной задачи

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

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

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

Как устроено физическое хранение таблиц в файловой базе 1С

Для начала выясним, как именно записываются данные. Файловая база данных 1С (файл с расширением .1cd) хранит записи таблиц построчно. Физически весь файл разбит на своеобразные «страницы» или блоки данных.

Рассмотрим подробнее механизм работы с этими страницами:

  1. До версии платформы 8.3.8 размер такого блока был жестко фиксированным и составлял 4 Кб.
  2. В современных форматах платформы появилась возможность гибко настраивать и увеличивать размер страниц до 8, 16, 32 и 64 Кб для оптимизации производительности под конкретные задачи.
  3. Данные внутри таблиц располагаются в виде непрерывных потоков внутри этих блоков именно строка за строкой.

Что это значит на практике? Если мы добавляем новую колонку в огромную таблицу, место под эту колонку будет зарезервировано в каждой строке, даже если она абсолютно пустая.

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

Выбор решения: дополнительная колонка или запрос?

Посмотрим на нашу изначальную задачу. Если колонка будет заполняться лишь раз на 1000 строк, добавление её в структуру таблицы — это огромная избыточность.

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

Пример логики запроса, который мы можем использовать вместо добавления колонки:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   НужныйДокумент.Ссылка КАК ДокументСсылка
    |ИЗ
    |   Документ.НужныйДокумент КАК НужныйДокумент
    |ГДЕ
    |   НужныйДокумент.КлючевойРеквизит = &ПараметрПоиска";
    
Запрос.УстановитьПараметр("ПараметрПоиска", ЗначениеИзРегистра);
Результат = Запрос.Выполнить();

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

Альтернативный вариант: Использование отдельного регистра сведений

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

В этот новый регистр мы будем записывать только те самые «редкие» связи: КлючИзБольшойТаблицы и СсылкаНаДокумент. При выполнении алгоритмов мы просто будем присоединять этот маленький регистр Левым соединением к нашей большой выборке. Таким образом, мы получаем отдельную, очень компактную таблицу (в ней будет ровно столько строк, сколько реально заполнено), и не раздуваем основную структуру данных.

Существует ли поколоночное хранение данных в 1С?

В ходе обсуждений разработчики часто шутят о переходе на СУБД Oracle ради колоночного хранения. Но мало кто знает, что в современной платформе 1С:Предприятие (начиная с версии 8.3.14) уже встроен собственный механизм поколоночного хранения данных.

Речь идет о механизме «Дата акселератор» (Data Accelerator). Это специализированная in-memory база данных (база данных в оперативной памяти), которая хранит информацию именно по колонкам.

Посмотрим, для чего он применяется: Дата акселератор используется совместно с механизмом копий баз данных. Он позволяет в десятки раз ускорить выполнение сложных, тяжелых аналитических запросов. При поколоночном чтении системе не нужно загружать в память всю строку со всеми ненужными реквизитами — она считывает только те колонки, которые непосредственно участвуют в расчетах. А начиная с версии платформы 8.3.27, Дата акселератор научился сбрасывать эти поколоночные данные на жесткий диск, что повысило отказоустойчивость системы.

Важное замечание об архитектурных стандартах платформы 1С

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

Согласно стандартам и логике платформы, первичным объектом в системе всегда выступает Документ. Именно Документ (как Регистратор) отражает хозяйственную операцию, генерирует движения и записывает данные в регистры. Использование регистра в качестве сущности, которая управляет документами, считается «кривой архитектурой».

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

← На главную