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

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

При росте товарного каталога в любой торговой компании неизбежно возникает задача визуализации ассортимента. Когда база данных насчитывает десятки тысяч позиций (например, от 50 000 номенклатурных единиц и более), а ее текущий вес уже составляет около 60 Гб, бездумное добавление изображений может привести к катастрофическим последствиям для производительности всей системы. Пользователи начнут жаловаться на медленное открытие карточек товаров, СУБД станет потреблять критический объем оперативной памяти, а системные администраторы столкнутся со сложностями при резервном копировании.

В этой статье мы подробно разберем, какие технические проблемы возникают при хранении медиафайлов непосредственно в SQL-базе данных, проанализируем архитектурные ограничения обычных форм «1С:Предприятия» и рассмотрим три эффективных сценария решения этой задачи.

В чем опасность хранения картинок непосредственно в базе данных SQL?

Многие начинающие разработчики совершают стандартную ошибку: они просто добавляют в карточку номенклатуры реквизит с типом ХранилищеЗначения и записывают туда бинарные данные картинок напрямую. Давайте разберем по шагам, почему этот подход является техническим тупиком для высоконагруженных баз данных:

  1. Раздувание TempDB и кэша СУБД. При выполнении тяжелых запросов или отчетов СУБД (например, MS SQL Server или PostgreSQL) считывает данные страницами. Наличие тяжелых бинарных данных (BLOB) в таблицах приводит к фрагментации страниц данных на физическом диске. СУБД тратит огромные ресурсы оперативной памяти на кэширование страниц с картинками, даже если в конкретном отчете вам нужны только остатки и цены.
  2. Проблемы с обслуживанием базы. Регулярное обслуживание СУБД (реиндексация таблиц, обновление статистики) начинает занимать в разы больше времени. База объемом в 60 Гб после загрузки неотформатированных фотографий со смартфонов (весом по 3–5 Мб каждая) может моментально вырасти до 150–200 Гб. Это увеличит «окно обслуживания» и сделает невозможным выполнение регламентных операций в ночное время.
  3. Отказ утилиты Тестирования и Исправления (ТИИ). При попытке запустить стандартное тестирование и исправление базы данных через Конфигуратор платформа 1С может аварийно завершить работу с ошибкой нехватки памяти (Out of Memory) или процесс затянется на десятки часов. Выгрузка базы в формат .dt также станет регулярной проблемой.
  4. Рост затрат на дисковую систему. Быстрые SSD-диски корпоративного класса (NVMe) стоят дорого. Хранить сотни гигабайт статичных картинок на таких дисках экономически нецелесообразно. Их место — на более медленных и дешевых сетевых хранилищах (NAS) или обычных HDD.

Решение 1. Вынос файлов во внешнее хранилище (тома хранения файлов)

Самым надежным и общепринятым методом является хранение путей к файлам, а не самих файлов внутри СУБД. В управляемых формах этот механизм реализован на уровне типовой Библиотеки Стандартных Подсистем (БСП). Однако на обычных формах (в конфигурациях вроде «Управление торговлей 10.3», «УПП 1.3» или «Комплексная автоматизация 1.1») этот функционал придется доработать вручную.

Рассмотрим алгоритм реализации собственного механизма томов хранения файлов. Вместо записи объекта Картинка в базу данных мы будем сохранять файл на сетевом ресурсе, а в информационной базе оставлять лишь относительный путь.

Для начала создадим общий сетевой каталог, к которому у всех пользователей терминального сервера или локальной сети будет доступ на чтение и запись (например, \\ServerShare\1C_Images\). При добавлении картинки в карточку товара выполним программный перенос файла на сервер и генерацию уникального имени на основе уникального идентификатора (GUID) номенклатуры.

Ниже приведен пример кода для сохранения выбранного файла во внешний сетевой каталог:


Процедура ЗагрузитьКартинкуНаДиск(ВыбранныйФайл, НоменклатураСсылка)
    
    СетевойКаталог = "\\ServerShare\1C_Images\";
    УникальноеИмяФайла = Строка(НоменклатураСсылка.УникальныйИдентификатор()) + ".jpg";
    ПолныйПутьНаСервере = СетевойКаталог + УникальноеИмяФайла;
    
    // Копируем файл из временной папки пользователя на сетевой ресурс
    Попытка
        КопироватьФайл(ВыбранныйФайл, ПолныйПутьНаСервере);
        
        // Записываем путь в реквизит карточки Номенклатуры или в регистр сведений
        ОбъектНоменклатура = НоменклатураСсылка.ПолучитьОбъект();
        ОбъектНоменклатура.ПутьККартинке = УникальноеИмяФайла;
        ОбъектНоменклатура.Записать();
        
        Сообщить("Картинка успешно сохранена во внешнем томе!");
    Исключение
        Предупреждение("Не удалось сохранить файл на сервере: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

При открытии карточки товара на обычных формах мы будем динамически считывать файл из сетевой папки и передавать его в элемент формы ПолеКартинки. Это позволит разгрузить базу данных и переложить всю работу с файлами на операционную систему.

Решение 2. Обязательное сжатие картинок и использование миниатюр (превью)

Даже если файлы хранятся на диске, при открытии списка номенклатуры или самой карточки оригинальные изображения весом в несколько мегабайт будут серьезно нагружать локальную сеть и клиентские ПК. Пользователи будут ощущать задержки (фризы) интерфейса при перелистывании товаров.

Для решения этой проблемы необходимо внедрить двухэтапную загрузку:

  1. Автоматический ресайз (изменение разрешения) при загрузке. Ограничьте максимальный размер оригинального изображения. Для информационных целей в 1С достаточно разрешения 800х800 пикселей. При загрузке картинки код должен перехватить ее и программно уменьшить.
  2. Генерация миниатюр (превью). Дополнительно создавайте маленькую копию изображения размером 100х100 или 150х150 пикселей весом не более 5–10 Кб. Именно эта миниатюра должна отображаться по умолчанию в карточке номенклатуры и списках. Оригинальный файл должен подгружаться только при нажатии пользователем на область превью для детального просмотра.

Для качественного сжатия файлов на сервере под управлением ОС Windows можно воспользоваться встроенным COM-объектом работы с графикой (WIA) или консольной утилитой ImageMagick. Разберем пример использования WIA для изменения разрешения картинки перед ее сохранением:


Функция СжатьИзображение(ПутьКФайлу, ПутьКудаСохранить, МаксШирина, МаксВысота) Экспорт
    
    Попытка
        Imager = Новый COMОбъект("WIA.ImageFile");
        Imager.LoadFile(ПутьКФайлу);
        
        // Проверяем, нужно ли уменьшать картинку
        Если Imager.Width > МаксШирина Или Imager.Height > МаксВысота Тогда
            Process = Новый COMОбъект("WIA.ImageProcess");
            Process.Filters.Add(Process.FilterInfos("Scale").FilterID);
            
            // Настройка фильтра масштабирования
            Process.Filters(1).Properties("MaximumWidth").Value = МаксШирина;
            Process.Filters(1).Properties("MaximumHeight").Value = МаксВысота;
            Process.Filters(1).Properties("PreserveAspectRatio").Value = Истина;
            
            Imager = Process.Apply(Imager);
            
            // Удаляем старый файл перед перезаписью
            Если НайтиФайлы(ПутьКудаСохранить).Количество() > 0 Тогда
                УдалитьФайлы(ПутьКудаСохранить);
            КонецЕсли;
            
            Imager.SaveFile(ПутьКудаСохранить);
            Возврат Истина;
        КонецЕсли;
    Исключение
        ЗаписьЖурналаРегистрации("СжатиеКартинок", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;
    
    Возврат Истина;
КонецФункции

Решение 3. Интеграция с веб-сайтом компании через Поле HTML-документа

Если у вашей компании есть собственный интернет-магазин, на который выгружаются все товары с качественными фотографиями, можно использовать сайт в качестве облачного хранилища картинок для 1С. Это один из самых производительных архитектурных паттернов:

Для реализации этого метода разместим на форме карточки номенклатуры элемент управления Поле HTML-документа (например, с именем ПолеHTMLПросмотра) и будем динамически загружать туда простейший HTML-код с тегом вывода картинки:


Процедура ОбновитьКартинкуНаФорме(НоменклатураСсылка)
    
    URLКартинки = "https://mysite.com/images/goods/" + СокрЛП(НоменклатураСсылка.Артикул) + ".jpg";
    
    // Формируем HTML-код для отображения картинки по центру с масштабированием под размеры окна
    HTMLКод = "<html>
              |<head>
              |<style>
              |body { margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; background-color: #f0f0f0; }
              |img { max-width: 100%; max-height: 100%; object-fit: contain; }
              |</style>
              |</head>
              |<body>
              |<img src=""" + URLКартинки + """ onerror=""this.src='https://mysite.com/images/no-image.png';"" />
              |</body>
              |</html>";
              
    ЭлементыФормы.ПолеHTMLПросмотра.УстановитьТекст(HTMLКод);
    
КонецПроцедуры

Использование свойства onerror в теге изображения гарантирует, что если на сайте для конкретной позиции еще нет фотографии, пользователь увидит аккуратную заглушку «Нет фото» вместо пустой страницы или стандартной ошибки браузера.

Резюме и рекомендации

Подводя итог анализу проблемы хранения изображений в базах данных «1С:Предприятие 8» объемом от 60 Гб на обычных формах, выделим ключевые правила построения надежной архитектуры:

  1. Откажитесь от хранения бинарных файлов внутри базы данных. Это убережет СУБД от чрезмерной фрагментации таблиц, снизит нагрузку на оперативную память сервера приложений и сохранит стабильную работу механизмов резервного копирования и ТИИ.
  2. Реализуйте хранение файлов на сетевом диске (в томах), если фотографии добавляются непосредственно менеджерами в 1С. На этапе загрузки обязательно внедряйте программное сжатие картинок до разрешения не более 800px по большей стороне с помощью COM-объектов или внешних консольных утилит.
  3. Используйте интеграцию со своим сайтом через поле HTML-документа, если интернет-магазин является первоисточником контента. Это самое элегантное и быстродействующее решение, которое сводит нагрузку на вашу локальную сеть и базу данных к абсолютному минимуму.
← На главную