直接在数据库中存储图像还是作为base64数据存储?

Goo*_*bot 53 mysql database base64 image imagemagick

在数据库中存储图像的常用方法是base64在存储数据之前将图像转换为数据.此过程将使尺寸增加33%.或者,可以将图像直接存储为BLOB; 例如:

$image = new Imagick("image.jpg");
$data = $image->getImageBlob();
$data = $mysqli->real_escape_string($data);
$mysqli->query("INSERT INTO images (data) VALUES ('$data')");
Run Code Online (Sandbox Code Playgroud)

然后显示图像

<img src="data:image/jpeg;base64,' .  base64_encode($data)  . '" />
Run Code Online (Sandbox Code Playgroud)

使用后一种方法,我们节省了1/3的存储空间.为什么base64在MySQL数据库中存储图像更常见?

更新:关于在数据库中存储图像的优点和缺点有很多争论,大多数人认为这不是一种实用的方法.无论如何,在这里我假设我们将图像存储在数据库中,并讨论了这样做的最佳方法.

Mar*_*ams 64

我认为图像(文件)通常不存储在base64编码的数据库中.相反,它们以二进制(blob)列(或文件)的原始二进制形式存储.

Base64仅用作传输机制,不用于存储.例如,您可以将base64编码图像嵌入到XML文档或电子邮件中.

Base64也是流友好的.您可以动态编码和解码(不知道数据的总大小).

虽然base64适合传输,但不要存储base64编码的图像.

Base64不提供任何校验和或任何有价值的存储空间.

与原始二进制格式相比,Base64编码将存储要求提高了33%.它还增加了必须从持久存储中读取的数据量,这通常仍然是计算中最大的瓶颈.读取较少的字节并在运行中对它们进行编码通常会更快.仅当您的系统是CPU绑定而不是IO绑定,并且您经常在base64中输出图像时,请考虑存储在base64中.

内嵌图像(嵌入在HTML中的base64编码图像)本身就是一个瓶颈 - 您通过网络发送了33%以上的数据,并且连续执行(Web浏览器必须等待内联图像才能完成下载页面HTML).

如果您仍希望存储base64编码的图像,请不要这样做,确保不将base64编码数据存储在UTF8列中,然后将其编入索引.

  • 很好的澄清; 但如果你搜索,你会发现许多教程存储为base64和一些用于二进制存储. (2认同)
  • Base64不提供校验和或任何具有任何值的存储。如果您提供一个带有参数的链接以用作存储,我将为您进行揭穿。:) (2认同)
  • 我不明白为什么这不是公认的答案,将图像存储在针对存储图像(如 S3)进行优化的外部 CDN/服务上还可以为您提供其他优势,例如缓存等。而不必为每个图像检索一个大字符串每次运行查询时数据库中的文档 (2认同)
  • 文件既可以位于 CDN 上,也可以位于公司的私人内部文件中。例如,CloudFront(自从提到了 S3)就允许使用私有 CDN。 (2认同)

use*_*434 61

  • Pro base64:您处理的编码表示是一个非常安全的字符串.它既不包含控制字符也不包含引号.后一点有助于防止SQL注入尝试.我不希望任何问题只是将值添加到"手动编码"SQL查询字符串.

  • Pro BLOB:数据库管理器软件知道它所期望的数据类型.它可以优化它.如果你将base64存储在一个TEXT字段中,它可能会尝试为它构建一些索引或其他数据结构,这对于"真正的"文本数据来说非常好用,但是没有意义,浪费了图像数据的时间和空间.并且它是较小的,如字节数,表示.

  • 转义输入可防止SQL注入攻击,而不是存储机制.我承认我从来不需要手工输入图像到查询中. (3认同)
  • 非常有用的比较。我担心的主要是安全问题。我不确定保存二进制文件是否可以为 SQL 注入打开任何安全漏洞。 (2认同)
  • “安全字符串”参数可能是使用 base64 进行传输而不是存储的原因。 (2认同)

ACP*_*Pan 7

只是想举一个例子,为什么我们决定将图像存储在 DB 中而不是文件或 CDN 中,它是存储签名的图像。

我们尝试通过 CDN、云存储、文件来实现,最终决定存储在 DB 中,并对这个决定感到高兴,因为当我们多次移动、升级脚本和迁移站点时,这在随后的事件中证明了我们是正确的。

就我而言,我们希望签名与属于文档作者的记录一起使用。

以文件格式存储可能会丢失它们或被意外删除。

我们在 MySQL 中将它存储为 blob 二进制格式,然后在文本字段中存储为基于 64 编码的图像。更改为 based64 的决定是由于某种原因导致较小的尺寸和更快的加载。由于某种原因,Blob 减慢了页面加载速度。

在我们的例子中,这个在 DB 中存储签名图像的解决方案(无论是 blob 还是 based64)是由以下因素驱动的:

  1. 大多数签名图像都非常小。
  2. 我们不需要索引存储在 DB 中的签名图像。
  3. 索引是在主键上完成的。
  4. 我们可能需要移动或切换服务器,将物理图像文件移动到不同的服务器,可能会因链接更改而导致找不到图像。
  5. 不好意思要求作者重新签名。
  6. 与将其公开为可以在安全受到损害的情况下下载的文件相比,将其保存在数据库中更安全。存储在 DB 中可以让我们更好地控制其访问。
  7. 任何未来的迁移、网页设计的更改、托管、服务器,我们都无需担心将签名文件名与物理文件进行协调,这一切都在数据库中!

交流电