При проектировании структуры метаданных у разработчиков нередко возникает соблазн задать строковым реквизитам универсальную большую длину — например, Строка(900) или Строка(1000). На первый взгляд это кажется удобным: отпадает необходимость контролировать длину строк при выгрузке данных, сопоставлении или обрезке через СокрЛП. Однако с точки зрения архитектуры базы данных и производительности СУБД такой подход приводит к серьезным проблемам.
Разберем подробно, как строковые типы данных обрабатываются платформой 1С и СУБД, с какими аппаратными и алгоритмическими ограничениями можно столкнуться, а также какие архитектурные шаблоны следует применять вместо создания широких строковых полей.
Проанализируем, как реляционные СУБД (например, Microsoft SQL Server или PostgreSQL) работают со строковыми полями различного типа:
VARCHAR / NVARCHAR): при хранении занимают фактический объем данных плюс служебные байты смещения. Однако при выполнении запросов с операциями сортировки (ORDER BY), группировки (GROUP BY) или соединений (JOIN) СУБД резервирует оперативную память под максимальный объявленный размер поля. Если в запросе участвуют сотни тысяч записей со строками по 900 символов, выделенного буфера памяти (Memory Grant) может не хватить, из-за чего промежуточные данные сбрасываются во временную базу на диск (TempDB), вызывая резкое падение производительности.CHAR / NCHAR): если в свойствах реквизита установлен признак фиксированной длины, платформа 1С дополняет каждую запись пробелами справа до максимального размера. Это приводит к неоправданному росту размера таблиц, увеличению объема резервных копий и повышенной нагрузке на сеть между сервером 1С и сервером СУБД.TEXT / VARCHAR(MAX)): такие поля выносятся за пределы основной страницы данных таблицы. По ним невозможно построить стандартный индекс СУБД, а в языке запросов 1С их нельзя использовать в условиях соединения и группировках без предварительного усечения функцией ПОДСТРОКА.Рассмотрим аппаратные лимиты реляционных баз данных, с которыми неизбежно сталкивается приложение при работе со строками повышенной ширины:
Строка(900) в индекс приведет либо к ошибке создания индекса, либо к падению транзакции при записи строки, фактический размер которой превысит лимит.Если реквизит имеет неограниченную длину, его использование в запросах требует обязательного применения функции ПОДСТРОКА. Выясним важную особенность поведения платформы:
Результат вычисления функции ПОДСТРОКА(Источник, Позиция, Длина) имеет строковый тип переменной длины. При этом длина результата будет считаться неограниченной, если исходное поле неограниченной длины, а параметр Длина превышает 1024 символа или не задан константой. Соответственно, при необходимости соединять таблицы по текстовым данным максимальная длина выборки не должна превышать 1024 символа.
Часто широкие реквизиты создаются как технические поля для сопоставления номенклатуры или контрагентов по внешним неструктурированным отчетам. Разберем, какими проверенными способами следует решать данную задачу:
Хеширование = Новый ХешированиеДанных(ХешФункция.MD5);
Хеширование.Добавить(ОчищеннаяСтрока);
ХешСтроки = Строка(Хеширование.ХешСумма);