Хранение данных URL в БД Монго

Я рассматриваю хранение data-urls в моем mongoDB вместо хранения ссылки на файл или использования GridFS.

URL данных:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMcAAAEsCAYAAAB38aczAAAgAElEQV

Все файлы, которые я храню, имеют размер JPG или PNG и имеют размер менее 1 МБ.

Мне интересно, считается ли это плохой практикой и как это влияет на производительность операций чтения и записи, сохраняя data-urls 1) в отдельной коллекции 2) в качестве метаданных в коллекции.

Я открыт для любых других предложений для небольшого хранилища файлов.

2 ответа

Решение

Во-первых, я бы не стал хранить данные в кодировке base64 в базе данных, которая вполне способна хранить двоичные данные. Это просто пустая трата пространства. Сохранять само изображение, а не его представление base64, т.е. не data : "VBORw0KGgoAAAANSUhEUgAAA...", но data : BinData("VBORw0KGgoAAAANSUhEUgAAA...") (первая строка для MongoDB, вторая - двоичные данные). Base64 увеличивает размер на 33%.

Кроме этого, я думаю, что это хорошо. Компромисс - 1 запрос, который захватывает все данные против нескольких запросов. Недостатком хранения больших кусков данных является то, что все данные должны быть в оперативной памяти на мгновение, но на 1 МБ это, вероятно, не проблема.

Однако вам следует убедиться, что вы не получите документ в ситуациях, когда вам не нужно изображение. 1 МБ не так уж много, но для коллекции с большим объемом чтения это катастрофа.

Я только что закончил решение этой проблемы. Это решение работает с Ajax, поэтому вы можете использовать fetchвызывает в Javascript с этим. Странно то, что нигде в Интернете это решение не может быть найдено, и поэтому я решил помочь другим, кто хочет работать с изображениями с данными uris :-)

Модель :

              cmsImage: { data: Buffer, contentType: String }

Хранение в MongoDB:

              let rawData = fs.readFileSync(`${root}public/uploads/` + file.originalname);
        let base64Data = Buffer.from(rawData).toString('base64');

        // upload this image
        let image = { 
            cmsImage: {
                data: base64Data,
                contentType: file.mimetype
            }    
        };

        // in this record in the database
        await this.model.findByIdAndUpdate(body.id, image);        

Получение из MongoDB и динамическое создание элемента изображения:

             // decode image from database as image uri
       let imageArray = new Int8Array(image.data.data);
       let decodedImage = new TextDecoder().decode(imageArray);

       // image
       let cmsImage = document.createElement("img");
       cmsImage.src = "data:" + image.contentType + ";base64," + decodedImage;
       cmsImage.alt = "image";
       cmsContent.appendChild(cmsImage);

Multer - использовать исходный файл для загрузки в базу данных.

            let storage = multer.diskStorage({
        destination: function (req, file, cb) {
          cb(null, './public/uploads')
        },
        filename: function (req, file, cb) {
          cb(null, file.originalname)
        }
      });

      this.upload = multer({ storage: storage });

загрузить в каталог

            this.upload.single(uploadImage)

  
Другие вопросы по тегам