将图像放入数据库的优点。
交易。保存 blob 时,您可以像提交任何其他数据库数据一样提交它。这意味着您可以将 blob 与任何关联元数据一起提交,并确保两者同步。如果磁盘空间不足?没有承诺。文件没有完全上传?没有承诺。愚蠢的应用程序错误?没有承诺。如果保持图像及其相关元数据彼此一致对您的应用程序很重要,那么数据库可以提供的事务可能是一个福音。
一个系统来管理。需要备份元数据和 blob?备份数据库。需要复制它们吗?复制数据库。需要从部分系统故障中恢复?重新加载数据库并向前滚动日志。DB 为一般数据带来的所有优势(卷映射、存储控制、备份、复制、恢复等)都适用于您的 blob。一致性更高,管理更轻松。
安全。数据库具有可以利用的非常细粒度的安全功能。模式、用户角色,甚至诸如“只读视图”之类的东西,以提供对数据子集的安全访问。所有这些功能也适用于保存 blob 的表。
集中管理。与 #2 相关,但基本上 DBA(好像他们没有足够的权力)可以管理一件事:数据库。现代数据库(尤其是大型数据库)在跨多台机器的大型安装中运行良好。单一管理来源简化了程序,简化了知识转移。
大多数现代数据库都可以很好地处理 blob。借助数据层中对 blob 的一流支持,您可以轻松地将 blob 从数据库流式传输到客户端。虽然您可以执行一些操作,但会一次性“吸入”整个 blob,但如果您不需要该工具,请不要使用它。研究数据库的 SQL 接口并利用其功能。没有理由将它们视为“大字符串”,它们被单独处理并将您的 blob 变成大的、内存吞噬、缓存粉碎的炸弹。
就像您可以为图像设置专用文件服务器一样,您可以在数据库中设置专用 Blob 服务器。给他们专用的磁盘卷、专用的模式、专用的缓存等。数据库中的所有数据都不相同,或者行为相同,没有理由将其配置为完全相同。好的数据库具有良好的控制水平。
从数据库中提供 blob 的主要任务是确保您的 HTTP 层实际上利用所有 HTTP 协议来执行服务。
许多幼稚的实现只是简单地抓取 blob,然后将它们全部倾倒到套接字中。但是 HTTP 有几个非常适合流式传输图像等的重要特性。特别是缓存标头、ETag 和分块传输以允许客户端请求 blob 的“片段”。
确保您的 HTTP 服务正确地处理所有这些请求,并且您的数据库可以成为一个非常好的 Web 公民。通过将文件缓存在文件系统中以供 HTTP 服务器提供服务,您可以获得“免费”的一些优势(因为一个好的服务器无论如何都会为“静态”资源做到这一点),但请确保如果您这样做,您尊重图像的修改日期等。
例如,有人请求 spaceshuttle.jpg,这是 2009 年 1 月 1 日创建的图像。最终在请求日期(例如 2009 年 2 月 1 日)缓存在文件系统上。之后,图像从缓存中清除(FIFO 策略, 或其他),然后有人在 2009 年 3 月 1 日再次请求它。好吧,现在它有一个 2009 年 3 月 1 日的“创建日期”,尽管它的创建日期实际上是 1 月 1 日。所以,你可以看到,特别是如果你的缓存经常转,客户端可能正在使用 If-修改后的标头可能会获得比实际需要更多的数据,因为服务器认为资源已更改,而实际上并未更改。
如果您将缓存创建日期与实际创建日期保持同步,则问题可能会更小。
但关键是,为了成为“优秀的网络公民”,需要仔细考虑整个问题,并为您和您的客户节省一些带宽等。
我刚刚为一个从数据库提供视频的 Java 项目完成了所有这些工作,这一切都是一种享受。