这个问题在这里已经有答案了:

在 Web 应用程序的上下文中,我的前老板总是说在数据库中放置对图像的引用,而不是图像本身。我倾向于同意存储 url 与存储 url 相比。将图像本身存储在数据库中是一个好主意,但在我现在工作的地方,我们在数据库中存储了很多图像。

我能想到的唯一原因可能是它更安全?您不希望有人直接链接到某个网址吗?但如果是这种情况,您始终可以让网站/服务器处理图像,就像 asp.net 中的处理程序一样,以便用户需要进行身份验证才能查看图像。我还认为从数据库中提取图像会损害性能。还有其他原因可以解释为什么将图像存储在数据库中是个好主意/不太好主意吗?


精确重复: 用户图片:数据库还是文件系统存储?
精确重复: 将图像存储在数据库中:是还是不是?
精确重复: 我应该将图像存储在数据库还是文件夹中?
精确重复: 您会将二进制数据存储在数据库或文件夹中吗?
精确重复: 将图片存储为文件或网络应用程序的数据库?
精确重复: 存储少量图像:blob 还是 fs?
精确重复: 将图像存储在文件系统或数据库中?

有帮助吗?

解决方案

如果你 不定期的 需要检索图像,并且该图像必须在多个不同的 Web 服务器上可用。但我认为仅此而已。

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

我们在这里讨论的是一种边缘情况,您可以通过利用数据库来避免为系统增加额外的复杂性。

除此之外,不要这样做。

其他提示

将图像放入数据库的优点。

  1. 交易。保存 blob 时,您可以像任何其他数据库数据一样提交它。这意味着您可以提交 blob 以及任何关联的元数据,并确保两者同步。如果磁盘空间不足?没有提交。文件未完全上传?没有提交。愚蠢的应用程序错误?没有提交。如果保持图像及其关联的元数据彼此一致对于您的应用程序很重要,那么数据库可以提供的事务可能会是一个福音。

  2. 一套系统即可管理。需要备份元数据和 blob?备份数据库。需要复制它们吗?复制数据库。需要从部分系统故障中恢复吗?重新加载数据库并前滚日志。DB 为一般数据带来的所有优势(卷映射、存储控制、备份、复制、恢复等)都适用于您的 blob。一致性更高,管理更轻松。

  3. 安全。数据库具有可以利用的非常细粒度的安全功能。架构、用户角色,甚至“只读视图”之类的东西都可以安全地访问数据子集。所有这些功能也适用于保存 blob 的表。

  4. 集中管理。与 #2 相关,但基本上 DBA(就好像他们没有足够的权力一样)需要管理一件事:数据库。现代数据库(尤其是较大的数据库)非常适合跨多台机器的大型安装。单一管理来源简化了程序,简化了知识转移。

  5. 大多数现代数据库都能很好地处理 blob。借助数据层中对 Blob 的一流支持,您可以轻松地将 Blob 从数据库流式传输到客户端。虽然您可以执行一些操作来一次性“吸入”整个 blob,但如果您不需要该功能,则不要使用它。研究数据库的 SQL 接口并利用其功能。没有理由将它们视为“大字符串”,将它们整体处理并将您的斑点变成大的、吞噬内存、破坏缓存的炸弹。

  6. 就像您可以为图像设置专用文件服务器一样,您可以在数据库中设置专用 Blob 服务器。为他们提供专用磁盘卷、专用模式、专用缓存等。数据库中的所有数据并不相同,或者行为相同,没有理由将其配置为完全相同。好的数据库具有精细的控制水平。

从数据库提供 blob 的主要问题是确保 HTTP 层实际上利用所有 HTTP 协议来执行服务。

许多幼稚的实现只是简单地抓取 blob,然后将它们批量转储到套接字中。但 HTTP 有几个非常适合流图像等的重要功能。特别是缓存标头、ETag 和分块传输,以允许客户端请求 Blob 的“片段”。

确保您的 HTTP 服务正确处理所有这些请求,并且您的数据库可以成为非常好的 Web 公民。通过将文件缓存在文件系统中以供 HTTP 服务器提供服务,您可以“免费”获得其中一些优势(因为好的服务器无论如何都会对“静态”资源执行此操作),但请确保如果您这样做,您尊重诸如修改日期之类的事情。对于图像。

例如,某人请求 spaceshuttle.jpg,这是 2009 年 1 月 1 日创建的图像。最终在请求日期(例如 2009 年 2 月 1 日)缓存在文件系统上。后来,该图像从缓存中清除(先进先出策略或其他),并且稍后有人在 2009 年 3 月 1 日再次请求它。好吧,现在它的“创建日期”是 2009 年 3 月 1 日,尽管它的创建日期实际上是 1 月 1 日。因此,您可以看到,特别是如果您的缓存周转很多,可能使用 If-Modified 标头的客户端可能会获取比实际需要更多的数据,因为服务器认为资源已更改,但实际上并未更改。

如果您使缓存创建日期与实际创建日期保持同步,那么这可能不是什么问题。

但重点是,为了成为“优秀的网络公民”,需要仔细思考整个问题,并为您和您的客户节省一些潜在的带宽等。

我刚刚为一个从数据库提供视频的 Java 项目经历了这一切,一切都很顺利。

我知道,如果您将图像存储在数据库中(甚至提及它),大多数数据库专业人员都会对您交叉手指并发出嘶嘶声。是的,当使用数据库作为任何类型的大块二进制数据的存储库时,肯定会对性能和存储产生影响(图像往往是无法标准化的最常见的数据位)。然而,在大多数情况下,图像的数据库存储不仅是允许的,而且 可取的.

例如,在我以前的工作中,我们有一个应用程序,用户可以将图像附加到他们正在编写的报告的几个不同点,并且这些图像必须在完成后打印出来。这些报告通过 SQL Server 复制进行移动,如果尝试以任何可靠性方式跨多个系统和服务器管理这些图像和文件路径,将会带来巨大的麻烦。将它们存储在数据库中为我们提供了所有这些“免费”,并且报告工具不必访问文件系统来检索图像。

我的一般建议是不要将自己限制于一种方法或另一种方法 - 采用适合情况的技术。文件系统非常擅长存储文件,数据库非常擅长根据请求提供小块数据。另一方面,我公司的一个产品需要将应用程序的整个状态存储在数据库中,这意味着文件附件也存储在数据库中。使用我们的数据库服务器 (SQL Server 2005),即使对于大型客户和数据库,我也尚未遇到明显的性能问题。

Microsoft 的 SQL 2008 通过 FileStream 功能为您提供了两全其美的功能 - 可能值得一试。 http://technet.microsoft.com/en-us/library/bb933993.aspx

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

最简单/最高效/最可扩展的解决方案是将图像存储在文件系统上。如果安全性是一个问题,请将它们放在 Web 服务器无法访问的位置,并编写一个处理安全性并提供文件的脚本。

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

如果您的应用程序在多个服务器上运行,我会将图像的参考副本存储在数据库中,然后根据需要将它们缓存在文件系统上。与尝试横向同步文件系统相比,这样做更容易出错。

如果您的应用程序位于单个服务器上,那么是的,坚持使用文件系统并让数据库维护数据的路径。

当然,大多数 SQL 数据库在设计时并未考虑到提供图像,但是将它们存储在数据库中会带来一定的便利。

例如,如果您已运行数据库并配置了复制。您立即拥有一个 HA 映像存储,而不是尝试进行一些基于 rsync 或 nfs 的文件系统复制。此外,使用一堆 Web 进程(或设计一些新服务)将文件写入磁盘会稍微增加您的复杂性。实际上,它只是更多的活动部件。

至少,我建议将有关图像的“元”数据(例如任何权限、谁拥有它等)和实际数据分成不同的表,这样切换到不同的数据存储将相当容易线。与某种 CDN 或缓存相结合应该可以在一定程度上为您提供相当好的性能,因此我认为这取决于该应用程序需要的可扩展性以及如何在实现的简易性之间取得平衡。

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

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

当数据库中存储了数 TB 的图像数据时,灾难恢复绝对没有乐趣。您最好找到一种更好的方法来分发数据以使其更加可靠等等......当然,所有开销(上面提到的)在复制等时都会成倍增加......

只是不要这样做!

这看起来真的像是一个 KISS(保持简单愚蠢)问题。文件系统可以轻松地处理存储图片文件,但在数据库中却不容易做到,而且很容易弄乱数据。当您只需担心文件安全性时,为什么要承受性能损失以及 SQL 和渲染中的所有困难呢?您还可以使用 NFS 或 CIFS 处理混合系统。文件系统是成熟的技术。更简单,更强大。

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

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

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

如果是需要偶尔取出的图像,并将它们保存在数据库中会让生活变得更轻松,我对此没有任何问题。

  • 数据数据库
  • 文件的文件系统
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top