Куда 1С на самом деле записывает содержимое реквизита типа ХранилищеЗначения
Содержание
Хранилище значений в 1С не создаёт отдельных файлов и каталогов. Содержимое реквизита типа ХранилищеЗначения хранится прямо в базе: в файловом варианте — внутри файла 1Cv8.1CD, в клиент-серверном — в двоичном поле таблицы объекта в СУБД (varbinary(max) в MS SQL Server, bytea в PostgreSQL). Значение сериализуется платформой во внутренний формат и при желании сжимается.
Отсюда простое следствие: найти «папку хранилища» на диске нельзя, зато можно найти таблицу и поле, где лежат данные, оценить их объём и решить, что с ним делать. Ниже — как это сделать в обоих вариантах работы, как настроить сжатие и чем такие реквизиты опасны для скорости и безопасности.
Как устроено хранилище значений и что в него можно положить
ХранилищеЗначения — тип платформы 1С:Предприятие 8.3. Он упаковывает любое сериализуемое значение в один блок двоичных данных и позволяет записать этот блок в реквизит справочника, документа, регистра сведений или табличной части.
Что обычно кладут внутрь:
- 🖼 картинки и сканы: фото товара, подпись, печать;
- 📄 файлы целиком в виде
ДвоичныеДанные; - 📊 таблицы значений, структуры, массивы — например, сохранённые настройки обработки;
- 🧾 служебные данные: снимки состояния, протоколы обмена, XML-ответы сервисов.
Платформа не «понимает» содержимое хранилища. Для неё это непрозрачный кусок байтов. Поэтому:
- по такому полю нельзя отбирать, сортировать и группировать в запросе;
- реквизит нельзя проиндексировать;
- ссылки, спрятанные внутри хранилища, не участвуют в контроле ссылочной целостности. Удаление помеченных объектов их не увидит, и после удаления в хранилище останется «битая» ссылка.
Не храните внутри ХранилищаЗначения ссылки, которые должны защищать объект от удаления. Для этого нужен обычный реквизит ссылочного типа.
Чем хранилище значений не является
Под похожими названиями в 1С живут ещё четыре механизма. Их часто путают:
| Механизм | Где лежат данные | Для чего |
|---|---|---|
Реквизит типа ХранилищеЗначения | Таблица объекта в базе | Произвольные данные объекта |
Временное хранилище (ПоместитьВоВременноеХранилище) | Память сервера, привязка к сеансу или форме | Передача данных между клиентом и сервером |
Хранилища настроек (ХранилищеОбщихНастроек и др.) | Служебные таблицы настроек в базе | Пользовательские настройки форм и отчётов |
| Безопасное хранилище БСП | Отдельный регистр сведений с привилегированным доступом | Пароли, токены, ключи |
| Хранилище конфигурации | Отдельный файл 1cv8ddb.1CD | Групповая разработка |
Дальше речь только о первой строке — о реквизите.
Файловая база: данные внутри 1Cv8.1CD
В файловом варианте вся информационная база — один файл 1Cv8.1CD в каталоге базы. Таблицы, индексы и содержимое хранилищ значений находятся внутри него. Отдельного файла под картинку или документ платформа не создаёт.
Как найти каталог базы:
- Откройте окно запуска 1С.
- Выделите базу в списке. Внизу окна появится строка подключения вида
File="D:\Base\Buh". - Перейдите в этот каталог в проводнике. Там лежит
1Cv8.1CD.
Рядом могут быть и другие файлы, например 1Cv8.cfl — кэш, а также служебные каталоги. Данные реквизитов в них не попадают.
Что это значит на практике:
- 📈 каждый сохранённый скан на 2 МБ увеличивает
1Cv8.1CDпримерно на эту же величину (минус то, что дало сжатие); - 🗑 после удаления объектов файл сам не уменьшается — место освобождается внутри, но размер на диске остаётся;
- 🔧 вернуть место помогает сжатие таблиц информационной базы в режиме «Тестирование и исправление» Конфигуратора или выгрузка-загрузка
.dt.
«Тестирование и исправление» и загрузка .dt требуют монопольного доступа: всех пользователей придётся вывести из базы. Перед этим сделайте резервную копию каталога базы.
Если база разрослась до нескольких гигабайт из-за вложений, пора подумать о переводе на клиент-серверный вариант или о хранении файлов вне базы (об этом ниже).
Клиент-серверная база: таблицы и поля в СУБД
В клиент-серверном варианте каждый объект метаданных — это таблица СУБД, а реквизит — поле. Имена служебные: _Reference45 для справочника, _Document112 для документа, _InfoRg1234 для регистра сведений. Реквизит получает имя вида _Fld567.
Тип поля для хранилища значений:
| СУБД | Тип поля |
|---|---|
| MS SQL Server | varbinary(max) (в старых базах встречается image) |
| PostgreSQL | bytea |
Как узнать, в какой таблице лежит реквизит
Имена таблиц и полей не совпадают с названиями в конфигураторе. Соответствие выдаёт функция платформы ПолучитьСтруктуруХраненияБазыДанных(). Её удобно вызвать из внешней обработки на сервере:
&НаСервере
Процедура ПоказатьХранениеНаСервере()
Объекты = Новый Массив;
Объекты.Добавить("Справочник.Номенклатура");
Структура = ПолучитьСтруктуруХраненияБазыДанных(Объекты, Истина);
Для Каждого СтрокаТаблицы Из Структура Цикл
Сообщить("Таблица: " + СтрокаТаблицы.ИмяТаблицыХранения);
Для Каждого Поле Из СтрокаТаблицы.Поля Цикл
Сообщить(" " + Поле.ИмяПоля + " -> " + Поле.ИмяПоляХранения);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Второй параметр Истина возвращает имена в терминах СУБД. Найдите в выводе имя реквизита и его поле хранения.
Где посмотреть сервер и имя базы данных
Строку подключения в окне запуска вида Srvr="srv1c";Ref="buh" дополняет консоль администрирования серверов 1С:Предприятия. Откройте кластер → «Информационные базы» → свойства базы. Там указаны тип СУБД, сервер баз данных и имя базы в СУБД. Именно в этой базе и лежат таблицы с полями хранилищ.
Оценить, сколько места занимают двоичные данные, можно средствами СУБД:
-- MS SQL Server: размер конкретной таблицы
EXEC sp_spaceused '_Reference45';
-- PostgreSQL: полный размер таблицы вместе с TOAST
SELECT pg_size_pretty(pg_total_relation_size('_reference45'));
💡 В PostgreSQL большие значения bytea уходят в отдельную TOAST-таблицу. Поэтому pg_relation_size покажет маленькую цифру, а реальный объём виден только через pg_total_relation_size.
Чтение таблиц напрямую через СУБД — только для диагностики. Записывать или удалять данные в таблицах 1С средствами SQL нельзя: это нарушает лицензионное соглашение и легко ломает базу.
Как настроить реквизит и сжатие данных
Отдельной «консоли» для хранилищ значений нет. Всё, что настраивается, делается в конфигураторе и в коде.
Создание реквизита
- В конфигураторе откройте объект метаданных, например справочник.
- Добавьте реквизит и в поле типа выберите
ХранилищеЗначения. - Сохраните и обновите конфигурацию базы данных.
Для типовой конфигурации на поддержке так делать не стоит: правку лучше вынести в расширение или хранить данные в отдельном регистре сведений, привязанном к объекту.
Запись, чтение и степень сжатия
Сжатие задаётся при создании значения, а не в свойствах реквизита:
// Запись: максимальная степень сжатия (0-9)
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
Объект.Скан = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных(9));
Объект.Записать();
// Чтение
Данные = Объект.Скан.Получить();
Если Данные = Неопределено Тогда
Сообщить("Реквизит пуст");
КонецЕсли;
Если второй параметр не передать, данные сохраняются без сжатия.
Когда сжатие помогает, а когда нет:
| Что храним | Эффект сжатия |
|---|---|
| XML, JSON, текст, таблицы значений | Заметный, объём падает в разы |
| BMP, несжатые TIFF | Хороший |
| JPEG, PNG, PDF со сканами, ZIP | Почти нулевой: данные уже сжаты |
Для уже сжатых форматов уровень 9 только тратит процессор сервера при записи.
Управляемые формы
В данные формы реквизиты типа ХранилищеЗначения не передаются. Работать с ними нужно на сервере: получить объект, вызвать Получить(), а для показа на клиенте поместить результат во временное хранилище через ПоместитьВоВременноеХранилище() и передать в форму адрес. Так обычно выводят картинку в поле формы.
Почему база тормозит из-за хранилищ и как это исправить
Сами по себе хранилища не медленные. Проблемы появляются, когда в них лежат мегабайты, а читают их чаще, чем нужно.
Типичные причины замедления:
- 🐢 Чтение объекта целиком.
Ссылка.ПолучитьОбъект()и обращение к реквизитам через точку от ссылки тянут данные объекта, а с ними и тяжёлое поле. Список из 500 номенклатур с фото по 1 МБ — это полгигабайта по сети. - 🐢 Хранилище в динамическом списке или отчёте. Поле попадает в выборку, хотя пользователю не показывается.
- 🐢 Обмены. Планы обмена выгружают объект целиком. Изменили наименование — улетел и скан.
- 🐢 Рост резервных копий.
.dtи бэкапы СУБД пухнут, восстановление идёт дольше.
Что делать:
- Вынести тяжёлые данные из объекта. Создайте регистр сведений
с измерением-ссылкой на владельца и ресурсом
ХранилищеЗначения. Объект остаётся лёгким, а данные читаются только по запросу. Так устроено хранение двоичных данных файлов в БСП. - Читать запросом только нужные поля. Вместо
ПолучитьОбъект()выберите запросом именно те реквизиты, которые нужны, без поля хранилища. - Включать сжатие для текстовых данных и не тратить его на JPEG и PDF.
- Хранить файлы в томах на диске. В конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) вложения можно хранить не в базе, а в томах — каталогах на сервере. Настройка находится в разделе
Администрирование, в блоке работы с файлами; быстрее всего найти её поиском по слову «том». После включения в базе остаются только сведения о файлах.
Как перенести уже накопленные данные
Если тяжёлый реквизит уже заполнен в тысячах объектов, переносите данные порциями:
- Создайте регистр сведений с измерением «Владелец» и ресурсом типа
ХранилищеЗначения. - Напишите обработку, которая выбирает запросом по 500-1000 ссылок, для каждой копирует значение в регистр и очищает старый реквизит, присваивая ему
Новый ХранилищеЗначения(Неопределено). - Каждую порцию записывайте в отдельной транзакции, чтобы не держать блокировки долго.
- Перепишите код и формы на чтение из регистра, проверьте на копии базы и только потом запускайте перенос в рабочей.
После переноса место в файловой базе освободится только после сжатия таблиц, а в СУБД — после её штатного обслуживания.
Кто может прочитать содержимое хранилища
Хранилище значений не шифрует данные. Сжатие — это не защита: распаковать его можно стандартными средствами. Доступ к содержимому определяется только правами на объект.
Кто увидит данные:
- 👤 любой пользователь, у которого есть право чтения объекта, если в конфигурации есть код или форма, выводящие хранилище;
- 🛠 администратор с доступом к Конфигуратору или внешним обработкам;
- 🗄 администратор СУБД: поле читается напрямую, а внутренний формат 1С можно распознать;
- 💾 любой, у кого оказался файл
1Cv8.1CD,.dtили бэкап СУБД.
Как защититься:
- Секреты — в безопасное хранилище. В БСП для паролей и токенов есть процедуры
ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище()и функцияОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(). Данные лежат в регистре, к которому у пользователей нет прав, и читаются только в привилегированном режиме. - Ограничить права на объект. Если в хранилище персональные данные (сканы паспортов, справки), закройте объект ролями и ограничением доступа на уровне записей.
- Защитить копии. Каталог файловой базы и бэкапы — только для учётной записи службы и администраторов. Бэкапы за пределами сервера шифруйте средствами архиватора или СУБД.
- Не давать прямой доступ к СУБД пользователям 1С. Учётная запись, под которой сервер 1С подключается к СУБД, не должна использоваться людьми.
Если нужно именно шифрование, а не разграничение прав, шифруйте данные до записи: например, средствами криптографии с сертификатом. Тогда в хранилище попадёт уже зашифрованный блок.
Частые вопросы
Можно ли посмотреть содержимое хранилища значений без программирования?
Получить() на сервере.Есть ли ограничение на размер одного хранилища значений?
Переносится ли содержимое хранилища при выгрузке в .dt?
.dt и увеличивают его размер.Можно ли сравнить два хранилища значений в запросе?
Почему после очистки реквизита файл базы не уменьшился?
.dt.