Почему обрезается строка в измерении регистра сведений и как правильно хранить длинные строки в 1С?

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

При разработке структуры базы данных в 1С часто возникает ситуация: мы создаем новый регистр сведений, добавляем измерение с типом Строка, задаем ему длину, например, 10 символов и указываем допустимую длину — «Переменная». Однако при попытке записать туда строку из 15 символов мы обнаруживаем, что она обрезается до 10. Разберем по шагам, почему это происходит, как работают настройки длины строки и как правильно проектировать хранение строковых данных, чтобы избежать ошибок СУБД.

Автоматическое усечение строк и настройка длины

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

Рассмотрим подробнее настройку свойства «Допустимая длина» в палитре свойств поля:

  1. Фиксированная: Если мы укажем этот вариант и попытаемся записать строку длиной 6 символов в поле с максимальной длиной 10, платформа искусственно дополнит эту строку пробелами справа до 10 символов. Это бывает необходимо в редких случаях, когда алгоритмам или внешним системам строго требуется наличие концевых пробелов.
  2. Переменная: Если указан этот вариант, короткая строка из 6 символов сохранится как есть, без добавления пробелов. Это экономит место в базе и исключает проблемы при поиске и сравнении значений. Но важно понимать: параметр «Переменная» не означает, что лимит длины снимается. Максимальная длина, указанная в конфигураторе, продолжает строго действовать, и все что больше нее — будет обрезано.

Архитектурные ограничения и почему не стоит делать длинные строковые измерения

Проанализируем ситуацию с точки зрения архитектуры базы данных. Измерения регистра сведений — это не просто поля таблиц. Совокупность всех измерений формирует первичный ключ записи регистра и обязательно входит в кластерный индекс таблицы на уровне СУБД.

Из этого вытекают жесткие ограничения:

  1. Запрет на неограниченную длину: Платформа 1С на базовом уровне запрещает использовать строки неограниченной длины в измерениях. Такие данные физически хранятся на уровне СУБД в отдельных таблицах (например, как BLOB или TEXT), они не могут входить в индексы и участвовать в быстром поиске.
  2. Ограничение длины ключа индекса: СУБД (например, MS SQL Server) имеют лимиты на размер ключа. Обычно максимальная длина ключа индекса составляет 900 байт. Для ориентировки: поле типа число занимает 16 байт ключа индекса, дата — 8 байт, ссылка на объект — 16 байт, а вот строка занимает около 3*n байт (где n — максимальная длина строки).
  3. Ошибка при записи: Даже если в конфигураторе система позволит установить длину строкового измерения, скажем, 1024, в реальности при попытке записать строку длиннее 300–450 символов (в зависимости от кодировки и других измерений) мы гарантированно получим ошибку уровня СУБД: «Длина элемента индекса превышает максимальную длину, равную 900 байт».

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

Правильные способы хранения длинных строк

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

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

2. Использование справочника. Если строковые значения часто повторяются (например, наименования каких-либо внешних объектов), создайте отдельный справочник. В измерение регистра сведений поместите реквизит с типом СправочникСсылка. Ссылка всегда занимает фиксированные 16 байт, что гарантирует компактность индекса и отсутствие проблем с СУБД.

3. Хеширование длинных строк. Если бизнес-логика требует обеспечения уникальности именно по длинному тексту, который превышает ограничения индексов, применим метод хеширования. В измерение регистра добавляется короткая строка (например, длиной 32 или 36 символов). При записи данных мы программно генерируем хеш-сумму исходного длинного текста (с помощью алгоритмов MD5, SHA-1 или встроенной функции хеширования) и записываем этот короткий хеш в измерение. Сам же исходный длинный текст помещаем в ресурс. Таким образом, уникальность контролируется по хешу в измерении, а ограничения СУБД не нарушаются.

Особенности корректировки данных при изменении длины

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

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

← На главную