当前位置: 首页 > news >正文

探讨图片以Base64存数据库的合理性

这是一个非常经典的技术选型问题。

将图片以Base64编码后存入数据库,这种做法有其特定的适用场景,但在大多数情况下,它被认为是一种次优方案反模式

下面我们从多个角度来深入探讨其合理性与弊端。

什么是Base64存储?

首先,简单回顾一下:Base64是一种用64个可打印ASCII字符(A-Z, a-z, 0-9, +, /)表示二进制数据的方法。它将3字节的二进制数据编码为4字节的文本数据。因此,编码后的数据大小会比原始二进制数据大大约33%

所谓“Base64存数据库”,就是指将图片文件转换成Base64字符串,然后将这个字符串存入数据库的TEXTLONGTEXT类型的字段中。

在MySQL中,可以使用TEXT、MEDIUMTEXT或LONGBLOB类型来存储Base64编码的图片数据。TEXT类型适用于较小的数据,而MEDIUMTEXT和LONGBLOB类型适用于较大的数据。例如:

CREATE TABLE image_table (
id INT PRIMARY KEY AUTO_INCREMENT,
image_data MEDIUMTEXT
);

合理性(优点):在特定场景下可考虑

这种方案并非一无是处,它在某些简单或特定的场景下有其价值:

  1. 极简架构,无需文件系统

    • 场景快速原型开发、简单的个人项目、或者SQLite这样的嵌入式数据库应用中。整个应用(包括数据和图片)就是一个数据库文件,管理和迁移非常方便,避免了处理文件路径和目录结构的复杂性。

  2. 天然的事务一致性

    • 场景图片与数据库记录有极强的原子性关联要求。例如,用户的头像必须和用户账户信息同时创建、更新或删除。如果使用外部文件存储,需要实现分布式事务来保证数据库记录和图片文件的删除操作一致,而Base64存储在数据库内,一个事务即可搞定

  3. 简化后端代码

    • 不需要编写单独的文件上传、处理、路由和访问控制逻辑。所有的CRUD操作都通过数据库接口完成,对于前端来说,可能只需要处理一个字段即可。

  4. 无缝兼容JSON/XML

    • 在API接口中,可以直接将图片数据作为JSON/XML的一个字段返回,前端无需再次发起请求获取图片,可以直接使用data:image/png;base64,...的形式在<img src>中显示。这对于非常小的图标极少量的、需要内联的图片来说很方便。


不合理性(缺点):在生产环境中问题突出

对于任何有流量、有性能要求、需要扩展的生产级应用,这种方案的缺点远远大于优点:

  1. 存储空间增加约33%

    • 如前所述,Base64编码会导致数据膨胀。这不仅浪费数据库存储空间,也会增加备份的大小和耗时。

  2. 数据库性能严重下降

    • 内存消耗数据库查询返回的结果集通常会被加载到内存中。一张几百KB的图片编码后可能变成1MB多的文本,如果一次查询返回10条带图片的记录,就会瞬间消耗掉10MB+的内存,极易导致内存溢出

    • 网络带宽:同样,巨大的文本数据在数据库服务器与应用服务器之间、应用服务器与客户端之间传输,会占用大量网络带宽,增加响应时间

    • 缓存失效数据库查询缓存(如MySQL的Query Cache)和内存中的数据集会因为这些大字段而变得效率极低,缓存中能存放的记录数急剧减少。

  3. 丧失图片文件的原生优势

    • 无法利用浏览器缓存:使用传统的<img src="url">方式,图片可以被浏览器缓存,用户再次访问时无需重复下载。而Base64内联图片每次都会随着HTML/JSON一起传输,无法被独立缓存

    • 无法使用CDN加速:CDN(内容分发网络)的核心是缓存静态文件(如图片、CSS、JS)。Base64图片不是独立的静态文件,无法被CDN缓存,所有用户都必须回源到应用服务器获取,失去了CDN的地理位置加速优势。

    • 无法享受HTTP/2的多路复用优势HTTP/2允许在同一个连接上并行传输多个小文件,效率很高。将图片内联回退到了类似HTTP/1.1的模式,多个图片无法并行加载

  4. 处理不便

    • 要对图片进行加工(如生成缩略图、加水印)必须先解码Base64字符串,恢复成二进制文件,处理完再编码回去,流程繁琐,CPU开销大。而文件存储方案可以直接对文件流进行操作。


推荐方案:

标准的、成熟的生产环境方案是:只将图片的元数据(metadata)和访问路径存入数据库,图片文件本身存储在别处

  1. 文件系统(本地或网络附加存储-NAS)

    • 最简单直接的替代方案。数据库只存储/images/2024/05/user_123_avatar.jpg这样的路径

    • 优点:简单、高效、直接利用操作系统文件缓存。

    • 缺点:扩容和备份复杂,需要自己处理文件同步(尤其是在集群部署时)。

  2. 对象存储(Object Storage)强烈推荐):

    • 使用云服务如 AWS S3、阿里云 OSS、腾讯云 COS、Google Cloud Storage,或自建兼容S3协议的服务(如MinIO)。

    • 优点

      • 无限扩展:无需担心磁盘空间。

      • 高可用和持久性:云服务商保证数据不丢失。

      • 高性能:通常自带全球CDN加速。

      • 成本低廉:按实际使用量付费,通常比数据库存储便宜得多。

      • 完善的API和权限管理(生成临时访问链接以实现安全控制)。

    • 数据库中只存储一个由对象存储返回的唯一文件URL或Key


----------完-----------


文章转载自:

http://1vFy6Rqe.rnqbn.cn
http://XZJCwc7t.rnqbn.cn
http://FyelFZ5N.rnqbn.cn
http://W8TdHvYZ.rnqbn.cn
http://OmaUJSv7.rnqbn.cn
http://xBIVEz9U.rnqbn.cn
http://pFQEZPED.rnqbn.cn
http://TCuBCzgZ.rnqbn.cn
http://wIPqM8Di.rnqbn.cn
http://cbZ2mIz0.rnqbn.cn
http://S3ZmO6IV.rnqbn.cn
http://g8lDnKen.rnqbn.cn
http://g9Z5X6sf.rnqbn.cn
http://PkwVYffI.rnqbn.cn
http://9IbrYpcj.rnqbn.cn
http://PUG782hA.rnqbn.cn
http://RrZ4bcXj.rnqbn.cn
http://L4ifpzOH.rnqbn.cn
http://aMSipp8x.rnqbn.cn
http://YMZsUK1b.rnqbn.cn
http://Pq2inTog.rnqbn.cn
http://Mos6aNDQ.rnqbn.cn
http://GhgGXp4E.rnqbn.cn
http://99ylhd1C.rnqbn.cn
http://N1Bc6M7g.rnqbn.cn
http://YEXVI6Kn.rnqbn.cn
http://qyVur9Ew.rnqbn.cn
http://7kYJ40zR.rnqbn.cn
http://xJ0lI35Z.rnqbn.cn
http://2Ty1trU0.rnqbn.cn
http://www.dtcms.com/a/379220.html

相关文章:

  • MoonBit 再次走进清华:张宏波受邀参加「思源计划」与「程序设计训练课」
  • RabbitMQ如何实现消息的持久化?
  • Crawlergo安装全流程
  • 完全背包问题 - 动态规划最优解法(Java实现)
  • 如何选择合适的双轴倾角传感器厂家提升水平监测准确性?
  • 洛谷PP5318 查找文献 (深度搜索与广度搜索)详解
  • 手机云服务是什么意思?
  • Linux 基础操作全攻略:从文件解压到服务器管理
  • web:ts的类类型
  • 初识StarRocks
  • linux常见的基础命令及其作用
  • 12 Prompt 模板化与参数化
  • 自动化车间无线安灯呼叫系统解决方案
  • Oracle APEX 如何运行页面时跳过登录页
  • list容器
  • Docker Compose:轻松管理多容器应用
  • 云蝠智能大模型呼叫新模型上线,拥抱AGI
  • 网站SEO内部优化一般包括哪些内容和方法
  • 18j621-3通风天窗图集pdf(免费高清版)
  • 以下是UniApp启动速度优化的深度方案
  • GoogLeNet实战:用PyTorch实现经典Inception模块
  • verilog中task的使用
  • SpringDoc OpenAPI集成spring boot3
  • 安卓13_ROM修改定制化-----安卓 13 系统 ROM 定制化与低版本系统的核心区别
  • yolo学习笔记02——yolo简介
  • OpenCV 开发 -- 图像算术运算
  • 字符串-43.字符串相乘-力扣(LeetCode)
  • java properties/反射基础
  • solidity的高阶语法4
  • Vue.js Data定义方式对比 data() { return {...} } 与 data: {} 的区别