在数据库中存储图像 - 是还是不是?

415

我正在使用一款将图片大量存储在数据库中的应用程序。你对此有何看法?我更倾向于将其位置存储在文件系统中,而不是直接存储在数据库中。

你认为这样做的利弊是什么?


好的,你可以使用事务性磁盘缓存来实现这两个功能。 - Lilith River
56个回答

26

这是一篇关于该主题的有趣白皮书。

存储在数据库或文件系统中的大型对象:BLOB还是不BLOB

答案是“取决于情况”。当然,这取决于数据库服务器及其处理blob存储的方法。这也取决于存储在blob中的数据类型以及如何访问该数据。

较小的文件可以使用数据库作为存储机制有效地存储和传递。较大的文件最好使用文件系统进行存储,特别是如果它们经常被修改/更新。(blob碎片化成为与性能有关的问题。)

还有一点要记住。支持使用数据库存储blob的原因之一是ACID合规性。然而,在白皮书中测试人员使用的方法(SQL Server的批量记录选项)使SQL Server吞吐量翻倍,实际上将ACID中的'D'改变成了'd',因为blob数据没有随事务的初始写入一起被记录。因此,如果完全的ACID合规性是您系统的重要要求,请在比较文件I/O和数据库blob I/O时将SQL Server写入的吞吐量数字减半。


25

还没有人提到但值得注意的是,在大多数文件系统中存储大量图像也存在问题。例如,如果按上述方法为每个图像文件命名主键,当你达到非常大量的图像时(例如数十万或数百万),尝试将所有图像放在一个大目录中就会遇到问题。

通常的解决方案是将它们哈希成平衡子目录树。


1
最好使用没有大目录问题的文件系统。 - Seun Osewa
8
我曾有一个应用程序,它有数百万个文件位于同一个目录下(服务器运行 RHEL 4),即使仅列出目录内容(通过管道输出到文件)也需要数天时间,并且生成的输出文件大小为数百兆字节。现在,这些文件存储在数据库中,我只有一个单独的文件,可以轻松移动或备份。 - Richard
1
@Seun Osewa:每个文件系统都有其限制...如果您知道有一个可以在同一目录中存储数百万条目而没有问题的文件系统,请告诉我! - Guillaume
1
@Seun Osewa:数据库现在已经达到28GB,有5.4M条记录。我最终不得不对数据库表进行分区,因此我需要备份几个大约5GB大小的文件。现在将单独的图像移动到Amazon S3,所以我只需要在数据库中存储文件名(Amazon可以进行备份)。 - Richard
我们的系统中有超过1000万张图像文档。为了分散存储,每个子文件夹中都不超过大约6万张图像。我们拥有接近半个 TB 的图像,并且没有任何问题。 - Andrew Neely
显示剩余6条评论

22

有一件没有被提到的事情是数据库能够保证原子操作、事务完整性并处理并发。甚至在文件系统中,参照完整性也会失效——那么你怎么知道你的文件名是否仍然正确?

如果你把你的图片存储到一个文件系统里,当你正在写入新版本或者删除文件时,有人正在读取这个文件——会发生什么?

我们使用blob是因为它们更容易管理(备份、复制、传输)。对我们来说,它们的表现很好。


某个图像同时进行两次更新的可能性有多大? - Arafangion
1
你不需要同时更新就会出现问题 - 它可以是读取和写入。在我们的情况下,这几乎是肯定会发生的。 - Draemon

20

只将图片路径存储在数据库中存在的问题是无法强制维护数据库完整性。

如果被路径指向的实际图像不可用,则数据库会无意中出现完整性错误。

鉴于这些图像是需要寻找的实际数据,并且它们可以更容易地管理(图像不会突然消失)在一个集成的数据库中,而不必与某种文件系统进行接口交互(如果独立访问文件系统,则图像可能会突然“消失”),我建议直接将它们作为BLOB或类似对象存储。


17

我曾在一家公司工作,我们在 Oracle 8i (后升级到9i) 数据库中存储了1.55亿张图片,总共7.5TB。


5
当然。显然,数据库现在要大得多。将数据存储在数据库中意味着在不同站点复制数据库变得更加容易。 - graham.reeds
我看到了一个Oracle的演示,他们实际上可以将文件系统挂载到数据库中,或者类似的操作。你知道你是否也是这样做的吗?(抱歉,我对Oracle一无所知,也许我在胡说八道。) - Stu Thompson
我不这么认为 - 它是将图像作为数据库存储的。数据库进行了积极的调整 - 我记得有多次讨论,关于随着字段的添加和删除,图像大小会发生变化的问题。一切都是边界对齐的。 - graham.reeds

14
通常情况下,我强烈反对将基础设施中最昂贵且最难扩展的部分(即数据库)放置所有负载。但另一方面,这大大简化了备份策略,特别是当您有多个Web服务器并需要以某种方式保持数据同步时。
像大多数其他事情一样,这取决于预期的规模和预算。

13
我们已经实现了一个文档成像系统,它将所有的图像存储在SQL2005的blob字段中。目前有几百GB的数据,并且我们看到了极好的响应时间和很少或没有性能下降。此外,为了符合监管合规性要求,我们有一个中间件层,将新发布的文档归档到一个光学碟库系统中,并将其作为标准的NTFS文件系统公开。
我们对结果非常满意,特别是出于以下方面:
1.备份和复制易用。 2.容易实现文档版本控制系统。

11
如果这是一个基于Web的应用程序,那么将图像存储在第三方存储交付网络上(例如Amazon的S3或Nirvanix平台)可能会有优势。

11

假设:应用程序是网络启用/基于Web的

我很惊讶没有人真正提到这一点...将其委派给专业人士-> 使用第三方图像/文件托管提供商

将您的文件存储在付费在线服务中,例如

另一个关于此问题的StackOverflow线程在这里

这个线程解释了为什么应该使用第三方托管提供商。

它非常值得。他们高效地存储它。没有从您的服务器上传到客户端请求的带宽等待。


10

如果你没有使用SQL Server 2008,而且有一些充分的理由需要将特定的图像文件放在数据库中,那么你可以采用“两者兼备”的方法,使用文件系统作为临时缓存,并使用数据库作为主要仓库。

例如,你的业务逻辑可以在提供图像文件之前检查磁盘上是否存在该文件,必要时从数据库中检索。这样做可以让你拥有多个Web服务器并减少同步问题。


+1 这还允许您存储原始图像,提供缓存/优化版本,同时允许稍后更改大小/压缩。 - Deebster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接