MySQL - Base64 与 BLOB
Posted
技术标签:
【中文标题】MySQL - Base64 与 BLOB【英文标题】:MySQL - Base64 vs BLOB 【发布时间】:2015-05-30 19:29:24 【问题描述】:为了简单起见,假设我正在开发一个像 Instagram 这样的移动应用程序。用户可以从服务器下载图片,也可以上传自己的图片。目前,服务器将所有图像(实际上只是小缩略图)作为 BLOB 存储在 mysql 数据库中。传输图像最常见的方法似乎是使用 Base64 编码,这让我有两个选择:
-
服务器将所有图像存储为 BLOB。要上传图片,客户端将其编码为 Base64 字符串,然后将其发送到服务器。服务器将图像 BACK 解码为二进制格式,并将其作为 BLOB 存储在数据库中。当客户端请求图像时,服务器将图像重新编码为 Base64 字符串并将其发送给客户端,然后客户端将其解码回二进制以显示。
服务器将所有图像存储为 Base64 字符串。要上传图片,客户端将其编码为 Base64 字符串并将其发送到服务器。服务器不进行编码或解码,只是将字符串存储在数据库中。当客户端请求图像时,Base64 字符串会返回给客户端,然后客户端将其解码以显示。
显然,选项 #1 需要在服务器上进行更多处理,因为必须在每个请求中对图像进行编码/解码。这使我倾向于选项 #2,但一些研究表明,在 MySQL 中存储 Base64 字符串的效率远低于将图像直接存储为 BLOB,并且通常不鼓励。
我当然不是第一个遇到这种情况的人,那么有没有人对最好的方法提出建议?
【问题讨论】:
选项 #3 首先是数据库中没有图像。他们有一个系统:文件系统。 我开始存储文件路径,但对 MySQL 最新版本的一些研究表明,将小文件(小于 1 或 2 mb)存储为 BLOB 实际上更有效。我的图片只有几 kb,所以这样维护起来要容易得多。 备份一个充满 BLOB 的数据库绝对是一场噩梦。复制它们很昂贵,备份它们也很昂贵,恢复它们非常痛苦,并且当它们变得太大时将它们拆分是非常痛苦的。除非您正在处理无关紧要的数据量,否则这最终会对您造成影响。使用像rsync
这样基本的东西可以很容易地复制磁盘上的文件。 MySQL 也不是这样。
【参考方案1】:
JSON 假定为 utf8,因此与图像不兼容,除非它们以某种方式编码。
Base64 的体积几乎是二进制 (BLOB) 的 8/6 倍。有人可能会争辩说它很容易负担得起。 3000 bytes
变成大约 4000 bytes
。
每个人应该能够接受任意 8 位代码,但不是每个人都可以。 Base-64 可能是不必处理 8 位数据的最简单且总体上最好的折衷方案。
由于这些“小”,我会将它们存储在表中,而不是文件中。但是,我会将它们存储在单独的表中,并在需要时将它们存储在适当的 id
中 JOIN
。这允许不需要图像的查询运行得更快,因为它们没有跨过 BLOB。
从技术上讲,TEXT CHARACTER SET ascii COLLATE ascii_bin
可以,但BLOB
更清楚地表明该列中实际上没有任何可用的文本。
【讨论】:
澄清一下,您是建议我将图像作为 Base64 存储在 BLOB 中,还是二进制数据本身并在每次提取时进行编码?至于您对 JOINing 的建议 - 这正是我正在做的事情,还有一个 Sphinx 索引。 Base64 的整个生命周期。然后你不需要在任何地方逃跑。所以,是的,BLOB 中的 Base64 没有编码,但初始 INSERT 除外。这是我的意见。 有趣,也许我会试一试。它肯定会节省大量 CPU,因为提取比插入更频繁。【参考方案2】:为什么要对网络上的图像进行 base64 编码?我认为你是从一个错误的假设开始的。
【讨论】:
你能澄清一下吗?现在,我将所有图像作为 Base64 编码的 JSON 对象发送,还带有一些元数据(因此客户端知道在收到图像后如何处理)。有没有办法将图像作为带有元数据的二进制对象(无编码)发送?客户端发布新图像怎么样?我的服务器将 Node.js 与 Express 用于 HTTP,以及 ws 用于某些 WebSocket 功能。 如果我们不通过网络发送它,我同意这是不好的。如果客户端想要显示存储在数据库中的图像,您有什么建议?我想一个网络链接是唯一的选择吗?但是我们的数据库在一列中已经有数千个 base64 编码的图像。任何帮助appreicated。 这应该是评论,肯定不是答案【参考方案3】:我不明白为什么 DB 服务器不应该始终将二进制数据保持在其本机形式。因此,使用 BLOB。 (但即使你确实将数据存储在 Base64 字符串中,也无需担心编码/解码性能,因为 IO 的影响会更大。)
我不明白为什么客户端应该以 base64 格式发送数据。为什么不使用简单的 HTTP 调用“流式传输”它?
【讨论】:
以上是关于MySQL - Base64 与 BLOB的主要内容,如果未能解决你的问题,请参考以下文章