有很多观点关于在数据库中存储 BLOB,我想知道是否有关于此事的实际调查或数据。
我们有一个应用程序存储与各种实体相关的图像,例如用户(他们的个人资料图片)和事件(活动现场照片)。应用程序数据库表中有一列存储了文件名,例如,1234joesmith.png
我们image
的服务器端代码从该文件名中形成一个完整的 URL,以返回到前端,例如https://ourapp.com/uploads/users/1234joesmith.png
。(这显然存在安全风险,我将单独处理该问题。)
我确信这样做是为了避免将 BLOB 放入数据库中并降低对数据库的访问速度。但是,它排除了这样一种架构:我们有多个带有负载平衡器或其他冗余中间件的服务器端实例,所有实例都使用同一个数据库(例如,可以是 AWS 数据库实例)。
我怀疑将 BLOB 排除在数据库之外的建议是基于旧技术并且已经过时了。例如,mysql 表行的总大小限制为 4kb,但 BLOB 和 TEXT 不计入该总数,除非每个这样的列只添加固定的几个字节。显然,BLOB 和 TEXT 是间接存储的,而不是内联存储在表行中。因此,mysql 的设计者显然已经考虑过存储 BLOB 的问题,并将尽量减少任何开销,因此它与文件系统访问没有太大区别(我怀疑)。
所以我的问题是:这些数字在哪里?实际数字在哪里?而不是手挥的数字。“我以为”我和其他人都可以做出推测。
答案1
对于网页,我建议回答以下问题:
- 将图像存储为文件
- 在数据库中存储图像的路径
- 使用以下方式构建网页
<img src=...>
- 这样 HTTP 和网络就可以完成工作,并且可以并行完成。也就是说,大概加快页面加载和用户体验。
对于那些认为数据库条目和图像分离会导致链接断开等问题的人,我想说
- 这是一个罕见的问题。
- 将之前的图像存储
INSERTing
到数据库中。这样,可能发生的最坏情况就是未引用的图像浪费磁盘空间,而不是“丢失”的图片。
如果您不是在谈论网页上的图像,那么请详细说明。
至于您对 MySQL 的一些评论:
BLOB
4KB 限制是错误的;忽略。64KB 等也是一样。但是,存储大于 16MB 的数据是“困难的” 。- 你应该使用
ENGINE=InnoDB
- InnoDB 有 4 种“row_formats”,每种格式都会将大部分或全部大块数据或文本“置于记录之外”。
- 从中获取图像比使用上面讨论的标签
BLOB
更麻烦(您的代码、MySQL 代码等) 。(在我看来。)img
挥手……是的,这个答案包含一些挥手。我反驳说,我已经在多个“产品”中尝试了各种实现(包括在 img 选项卡中使用 base54),这些产品有数百个网页。一般来说,页面的响应性“相似”。我认为这通常是判断此类操作(提供带有图像的网页)的主要标准。
我认为正在进行的主要活动是将大量数据从一个地方复制到另一个地方。
存储在 BLOB 中;使用回调(`)(如果我想在传送图像时修改它,我会使用这种技术。例如:磁盘上的大图像,但网页只需要缩略图。)
- Web 服务器启动一个 php 子进程
- 应用程序代码(php 语言)连接 MySQL
- BLOB 被提取到 buffer_pool 中
- php 在合适的 Header 的帮助下声明输出是图像
- 通过网络发送
- 关闭 MySQL 连接和 PHP 子连接
Base64(我尝试将其用于缩略图)
- 从磁盘读取数据放入 buffer_pool
- 复制到应用程序(php 或其他)
- 应用程序转换为 base 64
- 应用程序构建图片
- 通过网络发送
<img ...>
- 你的 Web 服务器(已在运行)知道如何从磁盘获取图像文件
- 它通过网络发送它。
以上所有内容都需要缓存,至少是从磁盘到 RAM。