При разработке структуры базы данных в 1С часто возникает ситуация: мы создаем новый регистр сведений, добавляем измерение с типом Строка, задаем ему длину, например, 10 символов и указываем допустимую длину — «Переменная». Однако при попытке записать туда строку из 15 символов мы обнаруживаем, что она обрезается до 10. Разберем по шагам, почему это происходит, как работают настройки длины строки и как правильно проектировать хранение строковых данных, чтобы избежать ошибок СУБД.
Выясним причину, по которой строка «теряет» символы. При попытке записать значение, превышающее заданную длину типизированного поля (будь то измерение, реквизит или ресурс), платформа 1С не генерирует ошибку и не выдает предупреждений. Она автоматически «молча» обрезает передаваемую строку до установленного в конфигураторе максимума (в нашем случае — до 10 символов).
Рассмотрим подробнее настройку свойства «Допустимая длина» в палитре свойств поля:
Проанализируем ситуацию с точки зрения архитектуры базы данных. Измерения регистра сведений — это не просто поля таблиц. Совокупность всех измерений формирует первичный ключ записи регистра и обязательно входит в кластерный индекс таблицы на уровне СУБД.
Из этого вытекают жесткие ограничения:
Поэтому использование длинных строк в измерениях регистра считается плохой практикой и признаком непродуманной архитектуры.
Рассмотрим, как правильно решить задачу, если нам необходимо хранить длинный текст, связанный с записью регистра сведений.
1. Перенос данных в ресурсы. Если строковое значение носит исключительно описательный характер (например, длинный комментарий, примечание), не формирует уникальность записи и по нему не требуется строить частые отборы в запросах, его следует перенести из раздела «Измерения» в «Ресурсы» или «Реквизиты». Ресурсы не входят в индекс ключа, и в них абсолютно безопасно хранить строки даже неограниченной длины.
2. Использование справочника. Если строковые значения часто повторяются (например, наименования каких-либо внешних объектов), создайте отдельный справочник. В измерение регистра сведений поместите реквизит с типом СправочникСсылка. Ссылка всегда занимает фиксированные 16 байт, что гарантирует компактность индекса и отсутствие проблем с СУБД.
3. Хеширование длинных строк. Если бизнес-логика требует обеспечения уникальности именно по длинному тексту, который превышает ограничения индексов, применим метод хеширования. В измерение регистра добавляется короткая строка (например, длиной 32 или 36 символов). При записи данных мы программно генерируем хеш-сумму исходного длинного текста (с помощью алгоритмов MD5, SHA-1 или встроенной функции хеширования) и записываем этот короткий хеш в измерение. Сам же исходный длинный текст помещаем в ресурс. Таким образом, уникальность контролируется по хешу в измерении, а ограничения СУБД не нарушаются.
Посмотрим на важный нюанс. Если вы обнаружили, что строка обрезается, увеличили длину измерения в конфигураторе (в разумных пределах) и пытаетесь просто перезаписать ранее обрезанные данные новым полным значением — у вас это не получится. Поскольку измерение входит в состав ключа записи, система воспримет новую, более длинную строку как совершенно новый набор измерений. В результате создастся новая запись-дубль, а старая (обрезанная) никуда не исчезнет.
Для точечного изменения значения самого измерения в уже существующих строках регистра необходимо программно использовать объект МенеджерЗаписи. С его помощью можно считать старую запись по старому ключу, удалить её, а затем записать новые данные с правильным значением измерения.