Хранение графических файлов непосредственно в рабочей базе 1С приводит к стремительному росту объема таблиц СУБД, замедлению создания резервных копий и повышенной нагрузке на дисковую подсистему. Когда администраторы запрещают использовать общие сетевые папки (SMB-ресурсы), разработчики часто приходят к идее выноса файлов в отдельную сервисную базу 1С или внешнее хранилище. Проанализируем, как правильно организовать структуру хранения, выбрать оптимальный тип идентификатора для быстрого поиска и какие архитектурные альтернативы существуют.
При передаче изображения во внешнюю базу или сервис необходимо вернуть в основную базу уникальный ключ (идентификатор), по которому файл будет мгновенно считываться в дальнейшем. Рассмотрим основные варианты хранения идентификатора и особенности их работы в платформе 1С:
УникальныйИдентификатор в платформе 1С нельзя напрямую передавать в параметры запросов для фильтрации в секции ГДЕ. Поэтому на уровне базы данных идентификатор сохраняется как строка фиксированной длины (36 символов) с обязательной установкой свойства Индексировать. Поиск по индексированному строковому полю фиксированной длины в реляционных СУБД выполняется предельно быстро.Код справочника: Если для регистрации файлов используется отдельный справочник, проще всего записывать строковый идентификатор или GUID непосредственно в стандартный реквизит Код. Он уже проиндексирован на уровне платформы, что исключает создание избыточных реквизитов.Важно помнить: затраты СУБД на выборку записи по любому проиндексированному ключу (число, строка, ссылка) несоизмеримо малы по сравнению со временем передачи самого бинарного файла по сети. Поэтому главным критерием выбора типа является удобство работы с ним в запросах и коде 1С.
Если для хранения файлов решено использовать вспомогательную конфигурацию 1С, нельзя сохранять бинарные данные в реквизитах самого справочника. Поля типа ХранилищеЗначений размещаются СУБД в отдельных LOB-таблицах, и обращение к объекту справочника может приводить к избыточному чтению больших объемов данных в память.
Разберем правильную схему разделения метаданных:
Файлы, где хранятся только метаданные: Код (строковый GUID или MD5), дата загрузки, размер, расширение, имя файла и MIME-тип.ДвоичныеДанныеФайлов с измерением Файл (тип СправочникСсылка.Файлы, ведущее) и ресурсом Данные (тип ХранилищеЗначений).Посмотрим на пример извлечения двоичных данных по строковому идентификатору:
Функция ПолучитьДвоичныеДанныеПоКоду(Знач СтроковыйИдентификатор) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ДвоичныеДанныеФайлов.Данные КАК Данные
|ИЗ
| РегистрСведений.ДвоичныеДанныеФайлов КАК ДвоичныеДанныеФайлов
|ГДЕ
| ДвоичныеДанныеФайлов.Файл.Код = &Код";
Запрос.УстановитьПараметр("Код", СокрЛП(СтроковыйИдентификатор));
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Хранилище = Выборка.Данные;
Если Хранилище <> Неопределено Тогда
Возврат Хранилище.Получить();
КонецЕсли;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Выясним причину, почему для передачи бинарных файлов не рекомендуется использовать классические SOAP Web-сервисы 1С. При вызове SOAP-методов бинарные данные упаковываются в текстовый формат Base64. Это увеличивает объем передаваемого по сети трафика примерно на 33% и создает значительную нагрузку на процессор при кодировании и декодировании.
Вместо SOAP следует использовать встроенные HTTP-сервисы 1С. Они позволяют отдавать двоичные данные напрямую в теле HTTP-ответа:
Функция ИзображенияGET(Запрос)
Идентификатор = Запрос.ПараметрыЗапроса.Получить("id");
ДвоичныеДанные = ПолучитьДвоичныеДанныеПоКоду(Идентификатор);
Если ДвоичныеДанные = Неопределено Тогда
Возврат Новый HTTPСервисОтвет(404);
КонецЕсли;
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "image/jpeg");
Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);
Возврат Ответ;
КонецФункции
Использование вспомогательной базы 1С в качестве файлового хранилища порождает лишние накладные расходы: расходуются клиентские и серверные лицензии 1С, тратятся ресурсы на запуск серверных контекстов и обслуживание дополнительной конфигурации. Проанализируем более эффективные варианты:
HTTPСоединение отправляет файл методом PUT и получает ключ объекта. В базе 1С хранится только строка-идентификатор. При необходимости тонкий или веб-клиент может запрашивать картинку напрямую из S3 по HTTP-ссылке без участия сервера 1С.