在Web应用程序的上下文中,我的老板总是说在数据库中引用了一个图像,而不是图像本身。我倾向于同意在数据库中存储网址与图像本身是一个好主意,但在我现在工作的地方,我们会在数据库中存储大量图像。
我能想到的唯一原因可能是它更安全吗?你不希望有人直接链接到网址吗?但如果是这种情况,您可以随时让网站/服务器处理图像,例如asp.net中的处理程序,以便用户需要进行身份验证才能查看图像。我也在考虑从数据库中提取图像会损害性能。将图像存储在数据库中可能是一个好/不太好的想法的任何其他原因?
完全重复: User Images: Database or filesystem storage?
完全重复: Storing images in database: Yea or nay?
完全重复: Should I store my images in the database or folders?
完全重复: Would you store binary data in database or folders?
完全重复: Store pictures as files or or the database for a web app?
完全重复: Storing a small number of images: blob or fs?
完全重复: store image in filesystem or database?
答案 0 :(得分:48)
将图像放入数据库的优点。
交易。保存blob时,您可以像任何其他数据库数据一样提交它。这意味着您可以将blob与任何关联元数据一起提交,并确保两者同步。如果磁盘空间不足?没有提交。文件没有完全上传?没有提交。傻申请错误?没有提交。如果保持图像及其关联的元数据彼此一致对您的应用程序很重要,那么数据库可以提供的事务可以是一个福音。
要管理的一个系统。需要备份元数据和blob吗?备份数据库。需要复制它们吗?复制数据库。需要从部分系统故障中恢复?重新加载数据库并向前滚动日志。数据库通常为数据带来的所有优势(卷映射,存储控制,备份,复制,恢复等)都适用于您的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项目,这一切都很有效。
答案 1 :(得分:21)
如果偶尔需要检索图像,并且必须在几个不同的Web服务器上提供。但我认为这就是它。
我们在这里讨论一个边缘案例,您可以通过利用数据库避免为系统增加额外的复杂性。
除此之外,不要这样做。
答案 2 :(得分:13)
据我所知,如果您将图像存储在数据库中(甚至提及它),大多数数据库专业人员都会嘲笑您。是的,当使用数据库作为任何类型的大块二进制数据的存储库时,肯定存在性能和存储影响(图像往往是无法规范化的最常见的数据位)。但是,在大多数情况下,图像的数据库存储不仅是允许的,而且是可取的。
例如,在我以前的工作中,我们有一个应用程序,用户将图像附加到他们正在编写的报告的几个不同点,并且这些图像必须在完成时打印出来。这些报告是通过SQL Server复制进行的,它会引起巨大的麻烦,试图以多种可靠性管理多个系统和服务器上的这些图像和文件路径。将它们存储在数据库中为我们提供了所有“免费”,并且报告工具无需前往文件系统来检索图像。
答案 3 :(得分:8)
我的一般建议是不要将自己局限于一种方法或另一种方法 - 采用适合这种情况的技术。文件系统非常擅长存储文件,数据库非常擅长根据请求提供一口大小的数据块。另一方面,我公司的一个产品需要将应用程序的整个状态存储在数据库中,这意味着文件附件也会存在。使用我们的数据库服务器(SQL Server 2005),即使对于大客户和数据库,我还是遇到了可观察到的性能问题。
Microsoft的SQL 2008通过FileStream功能为您提供了两全其美的功能 - 可能值得一试。 http://technet.microsoft.com/en-us/library/bb933993.aspx
答案 4 :(得分:7)
将图像存储到数据库中的一个优点是它可以跨系统移植,并且独立于文件系统布局。
答案 5 :(得分:6)
最简单/最高性能/最具扩展性的解决方案是将您的图像存储在文件系统中。如果担心安全性,请将它们放在Web服务器无法访问的位置,并编写一个处理安全性并提供文件的脚本。
假设您的网络/应用服务器和数据库服务器是不同的计算机,您将通过将图像放入数据库中进行一些点击:(1)两台计算机之间的网络延迟,(2)数据库连接开销,(3)消耗每个服务图像的附加数据库连接。我会更关注最后一点:如果您的网站提供大量图片,那么您的网络服务器将消耗许多数据库连接,并可能耗尽您的连接池。
答案 6 :(得分:5)
如果您的应用程序在多个服务器上运行,我会将您的图像的参考副本存储在数据库中,然后根据需要在文件系统上缓存它们。这样做不仅仅是一种容易出错的错误,而不是试图横向同步文件系统。
如果您的应用程序位于单个服务器上,那么,请坚持使用文件系统并让数据库维护数据路径。
答案 7 :(得分:3)
大多数SQL数据库当然不是为设计图像而设计的,但在数据库中使用它们有一定的便利性。
例如,如果您已经运行了数据库并配置了复制。您立即拥有HA映像存储,而不是尝试使用某些基于rsync或nfs的文件系统复制。此外,拥有一堆Web进程(或设计一些新服务)来将文件写入磁盘会增加您的复杂性。真的,这只是更多动人的部分。
至少,我建议保留关于图像的“元”数据(例如任何权限,拥有它的人等)以及分成不同表的实际数据,这样就可以很容易地切换到不同的表数据存储下线。加上某种CDN或缓存应该会给你提供相当好的性能,所以我认为这取决于这个应用程序需要的可扩展性以及如何平衡它与易于实现。
答案 8 :(得分:2)
您不必存储该URL(如果您认为这是不安全的)。您可以只存储一个在其他位置引用该图像的唯一ID。
数据库存储往往比文件系统更昂贵,维护成本更高 - 因此我不会在数据库中存储大量图像。
答案 9 :(得分:1)
就是不要这样做!
答案 10 :(得分:1)
这看起来像是一个KISS(保持简单愚蠢)的问题。文件系统可以轻松处理存储图片文件,但在数据库中进行操作并不容易,并且容易弄乱数据。当您可以担心文件安全性时,为什么要在性能和性能以及sql和渲染中遇到所有困难?您还可以使用NFS或CIFS处理混合系统。文件系统是成熟的技术。更简单,更强大。
答案 11 :(得分:1)
我将图像存储在数据库中以供演示应用程序使用。我这样做的原因是安全 - 删除我不应该有的记录不是一个大问题,但删除我不应该有的文件可能是一个问题!
如果性能成为一个问题,我会调查是否真的有可能删除流氓文件。
答案 12 :(得分:1)
如果是定期从数据库中取出的图像,我总是会尝试使用文件系统。
如果是需要暂时拔出的图像,并将它们保存在数据库中会让生活变得更轻松,我完全没有问题。
答案 13 :(得分:-1)