При проектировании структуры регистров сведений в 1С специалисты периодически сталкиваются с ситуацией, когда в списке доступных типов для измерения отсутствует ХранилищеЗначения. В то же время данный тип легко можно выбрать для ресурса или реквизита регистра. Разберем подробнее, с чем связано это ограничение платформы и СУБД, а также рассмотрим практические способы решения этой задачи.
Выясним причину, почему платформа 1С накладывает строгое ограничение на использование типа ХранилищеЗначения в измерениях регистров сведений:
ХранилищеЗначения хранятся в бинарных типах большого объема (BLOB, VARBINARY(MAX), BYTEA). Система управления базами данных на физическом уровне запрещает использовать такие типы в составе уникальных и кластеризованных индексов.ХранилищеЗначения в платформе 1С не определены операторы сравнения (равенство, больше, меньше), а также логика сортировки и группировки. Система физически не может проверить две записи на совпадение при формировании ключа уникальности.ХранилищеЗначения нельзя применять конструкции ГРУППИРОВАТЬ ПО, УПОРЯДОЧИТЬ ПО или использовать их в условиях соединения таблиц в запросах.Проанализируем концептуальное различие между элементами регистра сведений:
Измерения служат ключевыми полями, по которым выполняется быстрый поиск, фильтрация и обеспечивается уникальность записей. В измерение записываются ключевые разрезы (например, Номенклатура, Контрагент, Организация).
Ресурсы и реквизиты предназначены для хранения конечных данных или дополнительной информации. Тип ХранилищеЗначения идеально подходит для размещения именно в ресурсе или реквизите (например, для хранения файлов, картинок или сериализованных структур данных).
Если по бизнес-логике требуется выполнять отбор или уникальную идентификацию записей, связанных с бинарными данными из ХранилищеЗначения, разберем по шагам проверенные архитектурные решения.
Наиболее эффективный способ — рассчитывать хэш от помещаемых в хранилище данных и записывать его в измерение типа Строка фиксированной длины (например, 32 символа для MD5 или 64 символа для SHA256). Само ХранилищеЗначения при этом размещается в ресурсе или реквизите.
Посмотрим на пример кода расчета хэш-суммы при записи в регистр:
// Подготавливаем двоичные данные для сохранения
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
// Вычисляем хэш-сумму
Хэшер = Новый ХешированиеДанных(ХешФункция.MD5);
Хэшер.Добавить(ДвоичныеДанные);
ХешСуммаСтрокой = Строка(Хэшер.Хеш);
// Записываем данные в регистр сведений
МенеджерЗаписи = РегистрыСведений.ХранилищеФайлов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ХешДанных = ХешСуммаСтрокой; // Измерение (Тип: Строка, 32)
МенеджерЗаписи.ДанныеФайла = Новый ХранилищеЗначения(ДвоичныеДанные); // Ресурс (Тип: ХранилищеЗначения)
МенеджерЗаписи.Записать();
Благодаря этому подходу поиск и отбор записей производятся по быстрому строковому индексу ХешДанных.
Если хэширование содержимого не требуется, а нужно просто связать запись с уникальным блоком данных, создается УникальныйИдентификатор. Его строковое представление (36 символов) записывается в измерение регистра сведений.
НовыйГУИД = Строка(Новый УникальныйИдентификатор);
МенеджерЗаписи = РегистрыСведений.ЗначенияПараметров.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ИдентификаторХранилища = НовыйГУИД; // Измерение (Тип: Строка, 36)
МенеджерЗаписи.Значение = Новый ХранилищеЗначения(СтруктураПараметров); // Ресурс
МенеджерЗаписи.Записать();
Рассмотрим еще один стандартный архитектурный подход — создание служебного справочника (например, справочника присоединенных файлов или хранилища объектов).
ХранилищеЗначения.СправочникСсылка.ХранилищеОбъектов).Этот вариант гарантирует поддержку ссылочной целостности платформой 1С и позволяет штатно индексировать элементы СУБД.