做或不做:将图像存储在数据库中

在一个networking应用程序的背景下,我的老上司总是说在数据库中引用了一个图像,而不是图像本身。 我倾向于同意,在数据库中存储url和图像本身是一个好主意,但是现在我的工作就是在数据库中存储大量的图像。

我能想到的唯一原因可能是更安全吗? 你不希望有人直接链接到一个url? 但是,如果是这样的话,你可以随时让网站/服务器处理图像,如在asp.net中的处理程序,以便用户需要进行身份validation才能查看图像。 我也认为从数据库中提取图像会使性能受到影响。 任何其他原因为什么它可能是一个好/不是很好的主意,将图像存储在数据库中?


准确重复: 用户映像:数据库还是文件系统存储?
精确重复: 在数据库中存储图像:是或不是?
完全重复: 我应该将我的图像存储在数据库或文件夹中吗?
完全重复: 你会将二进制数据存储在数据库还是文件夹中?
确切的重复:将 图片存储为文件或Web应用程序的数据库?
完全重复: 存储less量图像:blob或fs?
精确重复: 将图像存储在文件系统或数据库中?

如果有时需要检索图像,并且必须在多个不同的Web服务器上可用。 但我认为这是非常多的。

  • 如果不需要在多台服务器上使用,最好将它们放在文件系统中。
  • 如果必须在多台服务器上使用,并且系统中实际存在某种负载,则需要某种分布式存储。

我们正在谈论一个边缘案例,在这里您可以避免通过利用数据库来为系统增加额外的复杂性。

除此之外,不要这样做。

将图像放入数据库的优点

  1. 交易。 当你保存blob时,你可以像任何其他数据块一样提交它。 这意味着您可以将blob与任何关联元数据一起提交,并确保两者同步。 如果磁盘空间不足? 没有提交。 文件没有完全上传? 没有提交。 傻的应用程序错误? 没有提交。 如果保持图像及其相关元数据的一致性对于您的应用程序非常重要,那么数据库可以提供的交易可以是一个福音。

  2. 一个系统来pipe理。 需要备份元数据和blob? 备份数据库。 需要复制它们吗? 复制数据库。 需要从部分系统故障中恢复? 重新加载数据库并向前滚动日志。 数据库带给数据的所有优点(卷映射,存储控制,备份,复制,恢复等)适用于您的blob。 更一致,更轻松的pipe理。

  3. 安全。 数据库具有可以被利用的非常细粒度的安全function。 模式,用户angular色,甚至像“只读视图”的东西,以安全访问数据的一个子集。 所有这些function以及持有斑点的桌子也一样。

  4. 集中pipe理。 与#2相关,但基本上DBA(好像他们没有足够的权力)可以pipe理一件事情:数据库。 现代数据库(特别是较大的数据库)可以在多台机器上进行大型安装。 pipe理的单一来源简化了程序,简化了知识转移。

  5. 大多数现代数据库处理斑点就好了。 通过在数据层中实现一stream的blob支持,您可以轻松地将数据块中的Blobstream式传输到客户端。 虽然有一些操作可以做到,一次就“吸”整个blob,如果你不需要这个设备,那就不要使用它。 研究您的数据库的SQL接口并利用其function。 没有任何理由把它们当作“大string”来对待,这些string被大量地对待,把你的斑点变成大的记忆,吞噬,caching砸碎的炸弹。

  6. 就像您可以为图像设置专用文件服务器一样,您可以在数据库中设置专用的Blob服务器。 为他们提供专用的磁盘卷,专用模式,专用caching等。数据库中的所有数据都不相同,或者行为相同,没有理由对其进行全部configuration。 好的数据库具有良好的控制水平。

关于从数据库提供blob的主要挑战在于确保您的HTTP层实际上利用所有HTTP协议来执行服务。

许多天真的实现只是抓住blob,并将它们批量转储到socket上。 但是HTTP有几个非常适合stream式传输图像的重要function,特别是高速caching标题,ETags和分块传输,以允许客户端请求blob的“块”。

确保你的HTTP服务正确地遵守所有这些请求,你的数据库可以是一个非常好的Web公民。 通过将文件caching到HTTP服务器的文件系统中,您可以免费获得其中的一些优势(因为一个好的服务器会为“静态”资源做到这一点),但是要确保你这样做,兑现修改date等图像。

例如,某人请求spaceshuttle.jpg,这是2009年1月1日创build的映像。最终在请求date(例如2009年2月1日)caching在文件系统上。稍后,将映像从caching中清除(FIFO策略,或者其他),以及2009年3月1日之后再次请求。 那么,现在它有一个2009年3月1日的“创builddate”,即使它的创builddate真的是1月1日。所以,你可以看到,特别是如果你的caching转了很多,客户端可能会使用If-修改的头可能会获得比实际需要更多的数据,因为服务器THINKS的资源已经改变,实际上它没有。

如果将caching创builddate与实际创builddate保持同步,则这可能不是什么问题。

但重要的是,为了成为一个“良好的networking公民”,需要思考整个问题,并为您和您的客户节省一些带宽。

我刚刚完成了一个为数据库中的video提供服务的Java项目,这一切都是一种享受。

我知道,如果你把图像存储在数据库中(或者甚至提到它),大部分数据库专业人士都会交叉手指和嘶嘶声。 是的,当使用数据库作为任何types的大块二进制数据的存储库(图像只是趋向于不能被标准化的最常见的数据位)时,肯定存在性能和存储影响。 但是,绝大多数情况下,图像数据库存储不仅是可行的,而且是可取的

例如,在我以前的工作中,我们有一个应用程序,在这个应用程序中,用户将图像附加到他们正在编写的报告的几个不同点上,而这些图像在完成时必须打印出来。 这些报告是通过SQL Server复制来移动的,它将引入一个非常头疼的问题,试图在多个系统和服务器上以任何可靠的方式pipe理这些映像和文件path。 将它们存储在数据库中为我们提供了“免费”的所有function,报告工具无需到文件系统中检索图像。

我的一般build议是不要把自己局限于一种方法或其他方法 – 去适应这种情况的技术。 文件系统非常擅长存储文件,而数据库则非常擅长按要求提供一小块数据。 另一方面,我公司的产品中有一个需要将应用程序的整个状态存储在数据库中,这意味着文件附件也会存在数据库中。 使用我们的数据库服务器(SQL Server 2005),即使对于大型客户和数据库,我仍然遇到可观察到的性能问题。

微软的SQL 2008通过FileStreamfunction为您提供了两全其美的解决scheme – 值得一试。 http://technet.microsoft.com/en-us/library/bb933993.aspx

将图像存储到数据库的优点之一是可以跨系统移植,并且独立于文件系统布局。

最简单/最高性能/最具扩展性的解决scheme是将您的图像存储在文件系统上。 如果担心安全问题,请将其置于Web服务器无法访问的位置,然后编写处理安全性并提供文件的脚本。

假设您的Web /应用程序服务器和数据库服务器是不同的机器,您将通过将图像放入数据库中来实现一些命中:(1)两台机器之间的networking延迟,(2)数据库连接开销,(3)消耗额外的数据库连接每个图像服务。 我会更关心的最后一点:如果您的网站提供了大量的图像,您的Web服务器将消耗许多数据库连接,并可能耗尽您的连接池。

如果您的应用程序运行在多个服务器上,我会将图像的参考副本存储在数据库中,然后在文件系统上按需caching它们。 这样做只是less了一个容易出错的麻烦,而不是试图横向同步文件系统。

如果您的应用程序在单个服务器上,那么是的,坚持到文件系统,并让数据库保持数据的path。

大多数SQL数据库当然不是devise用来logging图像的,但是在数据库中使用它们有一定的便利。

例如,如果您已经有一个数据库正在运行并且已经configuration了复制。 您立即拥有HA映像存储,而不是尝试使用基于rsync或nfs的文件系统复制。 另外,将一些web进程(或者devise一些新的服务)写到磁盘上会增加你的复杂性。 真的,它只是更多的移动部分。

至less,我build议保留有关图像的“元数据”(如任何权限,拥有者等等),并将实际数据分成不同的表格,以便切换到不同的数据存储区相当容易线。 加上某种types的CDN或caching应该会给你带来相当不错的性能,所以我想这取决于这个应用程序需要怎样的可扩展性,以及如何在易于实现的情况下实现平衡。

您不必存储URL(如果您觉得这是不安全的)。 您可以只存储一个引用其他地方的图像的唯一ID。

数据库存储往往比文件系统更昂贵,维护成本也更高,因此我不会将大量的图像存储在数据库中。

当您有数TB的图像数据存储在数据库中时,灾难恢复是绝对没有乐趣的。 你最好find一个更好的方式来分配你的数据,使它更可靠等等…当然,所有的开销(上面提到的)在复制等时都是成倍增长的。

只是不要这样做!

这真的好像一个吻(保持简单愚蠢)的问题。 文件系统很容易处理存储图片文件,但在数据库中做起来并不容易,而且容易搞乱数据。 为什么只要担心文件的安全性,就可以在sql和渲染中获得性能和所有困难? 您也可以使用NFS或CIFS处理混合系统。 文件系统是成熟的技术。 更简单,更强大。

我将图像存储在演示应用程序的数据库中。 我这样做的原因是安全性 – 删除我不应该有的logging不是一个大问题,但删除我不应该有的文件可能是一个问题!

如果性能成为问题,我会调查是否真的有可能删除stream氓文件。

如果是定期从数据库中取出的图像,我总是试着使用文件系统。

如果是偶尔需要拔出的图像,将它们保存在数据库中会使生活变得更加简单,那么我就完全没有问题了。

  • 数据库
  • 文件的文件系统