所以我正在使用一个将图像大量存储在数据库中的应用程序。你对此有何看法?我更像是一种在文件系统中存储位置的类型,而不是直接将它存储在数据库中。
您认为利弊是什么?
答案 0 :(得分:350)
我负责管理许多TB图像的应用程序。我们发现在数据库中存储文件路径是最好的。
有几个问题:
答案 1 :(得分:140)
与大多数问题一样,它并不像听起来那么简单。在某些情况下,将图像存储在数据库中是有意义的。
另一方面,存在相关问题
答案 2 :(得分:99)
文件存储。 Facebook工程师对它进行了很好的讨论。一个要点是了解目录中文件的实际限制。
Needle in a Haystack: Efficient Storage of Billions of Photos
答案 3 :(得分:56)
这可能有点远,但如果您正在使用(或计划使用)SQL Server 2008,我建议您查看新的FileStream数据类型。
FileStream解决了将文件存储在数据库中的大部分问题:
然而,SQL的“透明数据加密”不会加密FileStream对象,所以如果这是一个考虑因素,你可能最好只将它们存储为varbinary。
来自MSDN文章:
Transact-SQL语句可以插入,更新,查询,搜索和备份FILESTREAM数据。 Win32文件系统接口提供对数据的流式访问 FILESTREAM使用NT系统缓存来缓存文件数据。这有助于减少FILESTREAM数据可能对数据库引擎性能产生的任何影响。不使用SQL Server缓冲池;因此,此内存可用于查询处理。
答案 4 :(得分:39)
数据库中的文件路径是肯定的方式 - 我已经听说过来自有TB图像的客户的故事,它变成了一个噩梦,试图将大量图像存储在一个数据库 - 单独的性能影响太大了。
答案 5 :(得分:35)
根据我的经验,有时最简单的解决方案是根据主键命名图像。因此,很容易找到属于特定记录的图像,反之亦然。但与此同时,您不会在数据库中存储关于图像的任何。
答案 6 :(得分:31)
这里的诀窍是不要成为狂热者。
这里要注意的一点是,pro文件系统阵营中没有人列出了特定的文件系统。这是否意味着从FAT16到ZFS的所有内容都能轻松击败每个数据库?
没有。
事实是,即使我们只讨论原始速度,许多数据库也会击败许多文件系统。
正确的做法是为您的确切方案做出正确的决定,为此,您需要一些数字和一些用例估算。
答案 7 :(得分:30)
在您必须保证参照完整性和ACID合规性的地方,需要将图像存储在数据库中。
您不能事务性地保证图像和存储在数据库中的图像的元数据引用相同的文件。换句话说,不可能保证文件系统上的文件只能在与元数据相同的时间和事务中被更改。
答案 8 :(得分:28)
正如其他人所说,SQL 2008附带了一个Filestream类型,允许您将文件名或标识符存储为数据库中的指针,并自动将图像存储在文件系统中,这是一个很好的场景。
如果您使用的是较旧的数据库,那么我会说如果您将其存储为blob数据,那么您实际上不会以搜索功能的方式从数据库中获取任何内容,因此最好将地址存储在文件系统中,然后以这种方式存储图像。
通过这种方式,您还可以节省文件系统的空间,因为您只需要节省确切的空间量,甚至可以节省文件系统上的压缩空间。
此外,您可以决定使用一些结构或元素进行保存,这些结构或元素允许您浏览文件系统中的原始图像,而无需任何数据库命中,或者将文件批量传输到另一个系统,硬盘驱动器,S3或其他方案 - 更新你的程序中的位置,但保持结构,再次尝试增加存储时试图将图像从数据库中带出来,并没有太大的影响。
也许,它还允许您根据常用的图片网址将一些缓存元素投入到您的网络引擎/程序中,这样您就可以将自己保存在那里。
答案 9 :(得分:27)
不经常编辑的小静态图像(不超过几个megs)应存储在数据库中。这种方法有几个好处,包括更容易移植(图像与数据库一起传输),更容易备份/恢复(图像备份数据库)和更好的可扩展性(一个包含数千个小缩略图文件的文件系统文件夹听起来像一个可扩展性的噩梦我)。
从数据库提供图像很简单,只需实现一个http处理程序,它将从DB服务器返回的字节数组作为二进制流提供。
答案 10 :(得分:26)
这是一篇关于这个主题的有趣的白皮书。
To BLOB or Not To BLOB: Large Object Storage in a Database or a Filesystem
答案是“这取决于”。当然,这取决于数据库服务器及其blob存储方法。它还取决于blob中存储的数据类型,以及如何访问这些数据。
使用数据库作为存储机制,可以有效地存储和传送较小尺寸的文件。较大的文件可能最好使用文件系统存储,特别是如果它们经常被修改/更新。 (blob碎片成为性能方面的问题。)
这是另外一点要记住的。支持使用数据库存储blob的原因之一是ACID合规性。但是,测试人员在白皮书中使用的方法(SQL Server的批量记录选项)使SQL Server吞吐量加倍,有效地将ACID中的“D”更改为“d”,因为未记录blob数据该事务的初始写入。因此,如果完全ACID合规性是系统的重要要求,则在将文件I / O与数据库blob I / O进行比较时,将数据库写入的SQL Server吞吐量数量减半。
答案 11 :(得分:25)
我还没有看到有人提到的一件事,但绝对值得注意的是,在大多数文件系统中存储大量图像也存在问题。例如,如果您采用上述方法并在主键之后命名每个图像文件,则在大多数文件系统上,如果在达到大量图像时尝试将所有图像放在一个大目录中,则会遇到问题(例如,数十万或数百万)。
一般的解决方案是将它们散列到一个平衡的子目录树中。
答案 12 :(得分:22)
没有人提到的是数据库保证原子操作,事务完整性和并发处理。甚至引用完整性也不在文件系统的窗口 - 所以你怎么知道你的文件名真的是正确的?
如果您在文件系统中有图像,并且有人在您编写新版本或甚至删除文件时正在读取文件 - 会发生什么?
我们使用blob因为它们也更容易管理(备份,复制,传输)。它们对我们很有用。
答案 13 :(得分:20)
仅将文件路径存储到数据库中的图像的问题是无法再强制数据库的完整性。
如果文件路径指向的实际图像变得不可用,则数据库无意中会出现完整性错误。
鉴于图像是正在寻找的实际数据,并且它们可以在一个集成数据库中更容易管理(图像不会突然消失),而不必与某种文件系统接口(如果文件系统是独立访问,图像MIGHT突然“消失”),我会直接将它们存储为BLOB等。
答案 14 :(得分:17)
在我以前工作的公司,我们在Oracle 8i(当时的9i)数据库中存储了1.55亿个图像。价值7.5TB。
答案 15 :(得分:14)
通常情况下,我非常反对花费最贵和最难扩展部分基础设施(数据库)并将所有负载放入其中。另一方面:它极大地简化了备份策略,特别是当您有多个Web服务器并且需要以某种方式保持数据同步时。
与其他大多数事情一样,这取决于预期的规模和预算。
答案 16 :(得分:13)
我们已经实现了一个文档成像系统,它将所有图像存储在SQL2005 blob字段中。目前有几百GB,我们看到了出色的响应时间,很少或没有性能下降。此外,在法规遵从性方面,我们有一个中间件层,可将新发布的文档存档到光学点唱机系统,该系统将它们作为标准NTFS文件系统公开。
我们对结果非常满意,特别是关于:
答案 17 :(得分:11)
假设:应用程序已启用Web /基于Web
我很惊讶没有人真正提到这一点......将其委托给其他专家 - > 使用第三方图片/文件托管服务提供商。
将您的文件存储在付费在线服务中,例如
另一个StackOverflow线程正在谈论这个here。
This thread解释了为什么要使用第三方托管服务提供商。
非常值得。他们有效地存储它。没有带宽从您的服务器上传到客户端请求等
答案 18 :(得分:11)
如果这是基于网络的应用程序,那么将图像存储在第三方存储交付网络(例如亚马逊的S3或Nirvanix平台)上可能会有优势。
答案 19 :(得分:10)
如果您没有使用SQL Server 2008并且有一些可靠的理由将特定的图像文件放入数据库中,那么您可以采用“两种”方法并将文件系统用作临时缓存并使用数据库作为主存储库。
例如,您的业务逻辑可以在提供之前检查光盘上是否存在图像文件,并在必要时从数据库中检索。这为您提供了多个Web服务器的功能和更少的同步问题。
答案 20 :(得分:7)
SQL Server 2008提供了两全其美的解决方案:The filestream data type。
像常规表一样管理它并具有文件系统的性能。
答案 21 :(得分:7)
这取决于您要存储的图像数量以及它们的大小。我过去曾使用数据库来存储图像,而且我的经验相当不错。
IMO,使用数据库存储图像的优点是,
一个。您不需要FS结构来保存图像
B.当要存储更多数量的项目时,数据库索引的性能优于FS树
C.智能调整的数据库在缓存查询结果方面表现良好
D.备份很简单。如果您具有复制设置并且内容从靠近用户的服务器传送,它也可以很好地工作。在这种情况下,不需要显式同步。
如果您的图像小(例如<64k)并且数据库的存储引擎支持内联(记录中)BLOB,则它会进一步提高性能,因为不需要间接(实现了引用的位置)。
当您处理少量大尺寸图像时,存储图像可能不是一个好主意。在db中存储图像的另一个问题是,创建,修改日期等元数据必须由您的应用程序处理。
答案 22 :(得分:7)
我最近创建了一个PHP / MySQL应用程序,它将PDF / Word文件存储在MySQL表中(到目前为止每个文件大到40MB)。
<强>优点:强>
<强>缺点:强>
我称我的实现成功,它负责备份要求并简化项目的布局。对于使用该应用程序的20-30人来说,性能很好。
答案 23 :(得分:7)
我不确定这是一个“现实世界”的例子,但我目前有一个应用程序存储交易卡游戏的详细信息,包括卡片的图像。虽然迄今为止数据库的记录数仅为2851条记录,但考虑到某些卡已多次发布并具有替代图形,实际上扫描图形的“主要方块”然后动态更有效。在请求时为卡片生成边框和杂项效果。
此图像库的原始创建者创建了一个数据访问类,该类根据请求呈现图像,并且它可以非常快速地查看和单个卡。
这也可以在发布新卡时简化部署/更新,而不是压缩整个图像文件夹并将其发送到管道并确保创建正确的文件夹结构,我只需更新数据库并让用户下载它再次。目前这个大小高达56MB,这不是很好,但我正在为未来的版本开发增量更新功能。此外,还有一个“无图像”版本的应用程序,允许那些通过拨号获得应用程序而没有下载延迟。
此解决方案迄今为止运行良好,因为应用程序本身作为桌面上的单个实例。有一个网站可以存档所有这些数据以供在线访问,但我绝不会使用相同的解决方案。我同意文件访问会更好,因为它可以更好地扩展到为图像提出的请求的频率和数量。
希望这不是太多喋喋不休,但我看到了这个主题,并希望从一个相对成功的中小规模应用程序中提供一些我的见解。
答案 24 :(得分:6)
我的经验我必须管理这两种情况:存储在数据库中的图像和文件系统上的图像,路径存储在db中。
第一个解决方案,即数据库中的图像,有点“干净”,因为您的数据访问层必须只处理数据库对象;但只有当你必须处理低数字时,这才是好的。
显然,处理二进制大对象时的数据库访问性能会降低,数据库维度会增长很多,导致性能再次下降......通常数据库空间比文件系统空间贵得多。
另一方面,在文件系统中存储大型二进制对象会导致您有必须同时考虑数据库和文件系统的备份计划,这对某些系统来说可能是一个问题。
采用文件系统的另一个原因是,您必须与第三方访问共享您的图像数据(或声音,视频等):在这几天我正在开发一个使用必须访问的图像的Web应用程序从“外部”我的Web场以这种方式,数据库访问检索二进制数据是根本不可能的。因此,有时也会有一些设计因素可以帮助您做出选择。
在进行此选择时,还要考虑在访问二进制对象时是否必须处理权限和身份验证:当数据存储在db中时,这些必需品通常可以更容易地解决。
答案 25 :(得分:4)
我曾经在图像处理应用程序上工作过。我们将上传的图像存储在类似/ images / [今天的日期] / [id号]的目录中。但是我们还从图像中提取元数据(exif数据)并将其存储在数据库中,同时还有时间戳等。
答案 26 :(得分:4)
在之前的项目中,我将图像存储在文件系统中,这导致了很多令人头疼的问题,包括备份,复制和文件系统与数据库不同步。
在我的最新项目中,我将图像存储在数据库中,并将它们缓存在文件系统上,并且效果非常好。到目前为止我没有遇到任何问题。
答案 27 :(得分:3)
在数据库中存储图像仍然意味着图像数据最终会在文件系统中的某处结束,但会被遮挡,因此您无法直接访问它。
+ VES:
-ves:
这两种方法都很常见并且很常见。看看优缺点。无论哪种方式,你都必须考虑如何克服这些缺点。存储在数据库中通常意味着调整数据库参数并实现某种缓存。使用文件系统需要您找到一些方法来保持文件系统+数据库同步。
答案 28 :(得分:3)
街上的一句话是,除非你是一个数据库供应商试图证明你的数据库可以做到这一点(比如说,微软吹嘘Terraserver在SQL Server中存储了大量的图像),这不是一个好主意。当替代方案 - 在文件服务器上存储图像和数据库中的路径更加容易时,为什么要这么麻烦? Blob字段有点像SUV的越野能力 - 大多数人不使用它们,那些经常遇到麻烦的人,然后有些人这样做,但只是为了它的乐趣。
答案 29 :(得分:3)
第二个关于文件路径的建议。我曾经做过几个需要管理大型资产收集的项目,任何直接在数据库中存储东西的尝试都会导致长期的痛苦和挫折。
我能想到的关于将它们存储在数据库中的唯一真正的“专业人士”是个人图像资产的易用性。如果没有文件路径可供使用,并且所有图像都直接从数据库中流出,则用户无法找到他们无法访问的文件。
但是,似乎可以通过中间脚本从Web不可访问的文件存储中提取数据来更好地解决这个问题。因此,数据库存储并非真正必要。
答案 30 :(得分:2)
我是企业文档管理系统的首席开发人员,其中一些客户存储了数百GB的文档。 Terabytes在不太遥远的未来。我们使用文件系统方法出于本页提到的许多原因加上另一个:归档。
我们的许多客户必须遵守行业特定的归档规则,例如存储到光盘或以非专有格式存储。此外,您可以灵活地向NAS设备添加更多磁盘。如果您的文件存储在数据库中,即使使用SQL Server 2008的文件流数据类型,您的存档选项也会变得更加狭窄。
答案 31 :(得分:1)
正如有人提到的,“它取决于”。如果数据库中的存储应该是文件系统的1对1花式替换,那么它可能不是最佳选择。
但是,如果数据库后端将提供额外的值,而不仅仅是blob的序列化和存储,那么它可能是真正意义上的。
您可以查看WKT Raster这是一个旨在开发PostGIS中的栅格支持的项目,该项目又可以作为PostgreSQL数据库系统的地理空间扩展。 WKT Raster背后的理念不仅是定义光栅序列化和存储的格式(使用PostgreSQL系统),而且比存储更重要的是指定可从SQL访问的数据库端高效图像处理。简而言之,我们的想法是将操作权重从客户端转移到数据库后端,因此它尽可能地靠近存储本身。作为PostGIS的WKT Raster专门用于特定域GIS的应用程序。
要获得更完整的概述,请查看系统的website和presentation(PDF)。
答案 32 :(得分:1)
您的网络服务器(我假设您使用的是)用于处理图像,而数据库则不是。因此,我会在可能的一面投票。
只存储数据库中的路径(也可能是文件信息)。
答案 33 :(得分:1)
我会亲自将大数据存储在数据库之外。
优点:将所有内容存储在一起,轻松访问数据文件,轻松实现基础设施 缺点:降低数据库性能,许多页面拆分,可能的数据库损坏
答案 34 :(得分:1)
我们在表中存储图像的唯一原因是因为每个表(或每个工作范围的表集)都是临时的,并且在工作流结束时被删除。如果有任何类型的长期存储,我们肯定会选择存储文件路径。
还应该注意,我们在内部使用客户端/服务器应用程序,因此无需担心Web界面。
答案 35 :(得分:1)
如果您需要在文件系统上存储大量图像,需要考虑以下几点:
答案 36 :(得分:0)
通过线路从数据库中提取大量二进制数据将导致巨大的延迟问题,并且无法很好地扩展。
在数据库中存储路径,让您的网络服务器承担负担 - 这就是它的设计目标!
答案 37 :(得分:0)
我会选择两种解决方案,我的意思是......我将开发一个litle组件(EJB),它将图像存储在数据库中,并将此图像的路径存储到服务器中。如果我们有新图像或更新的原始图像,则仅更新此DB。然后我还将路径存储在业务DB中。
从应用程序的角度来看,我将始终使用文件系统(从业务数据库中检索路径),通过这种方式,我们将修复备份问题,并避免可能的性能问题。
唯一的缺点是我们将存储相同的图像2次...好处是内存便宜,加油!。
答案 38 :(得分:0)
如果您使用的是Teradata,那么Teradata Developer Exchange会有一篇关于加载和检索lobs和blob的详细文章。
http://developer.teradata.com/applications/articles/large-objects-part-1-loading
答案 39 :(得分:0)
对于大量小图片,数据库可能会更好。
我有一个带有许多小缩略图的应用程序(每个2Kb)。当我把它们放在文件系统上时,由于文件系统的块大小,它们每个消耗8kb。空间增加400%!
有关块大小的更多信息,请参阅此帖子: What is the block size of the iphone filesystem?
答案 40 :(得分:0)
我使用过许多数字存储系统,他们都将数字对象存储在文件系统中。他们倾向于使用分支方法,因此文件系统上会有一个存档树,通常从输入年份开始,例如2009年,子目录将是月份,例如8月8日,下一个目录将是例如11,有时它们也会使用小时,然后文件将以记录持久性ID命名。使用BLOBS有其优势,我听说它经常用于化学工业的IT部分,用于存储数千或数百万的照片和图表。它可以提供更细粒度的安全性,单一的备份方法,可能更好的数据完整性和改进的媒体间搜索,Oracle在他们用来调用Intermedia的软件包中有很多这方面的特性(我认为它现在被称为其他东西)。文件系统还可以通过诸如XACML或其他XML类型安全对象的系统提供粒度安全性。有关示例,请参阅Fedora Object Store的D空间。
答案 41 :(得分:0)
我几乎从未将它们存储在数据库中。最佳方法通常是将图像存储在由中央配置变量控制的路径中,并根据数据库表和主键(如果可能)命名图像。这为您提供了以下优势:
答案 42 :(得分:0)
尝试使用SQL模仿文件系统通常是一个糟糕的计划。如果你坚持使用文件系统进行外部存储,你最终会用相同或更好的结果编写更少的代码。
答案 43 :(得分:0)
数据库
文件的文件系统
答案 44 :(得分:0)
我会采用文件系统方法。无需使用图像创建或维护数据库,从长远来看,它将为您节省一些重大的麻烦。
答案 45 :(得分:0)
我会采用文件系统方法,主要是因为它具有更好的灵活性。考虑一下,如果图像数量变大,一个数据库可能无法处理它。使用文件系统,您可以简单地添加更多文件服务器,假设您使用的是NFS或kind。
文件系统方法的另一个优点是能够做一些花哨的东西,例如您可以使用Amazon S3作为主存储(将数据库中的URL保存而不是文件路径)。如果S3发生中断,您将回退到文件服务器(可能是包含文件路径的另一个数据库条目)。一些伏都教应用于Apache或您正在使用的任何Web服务器。
答案 46 :(得分:0)
文件系统,当然。然后,您可以使用所有操作系统功能来处理这些图像 - 备份,网络服务器,甚至只使用imagemagic等工具编写脚本批量更改。如果将它们存储在数据库中,那么您需要编写自己的代码来解决这些问题。
答案 47 :(得分:0)
您需要记住的一件事是数据集的大小。我相信Dillie-O是唯一一个甚至远远达到这一点的人。
如果您有一个小型的单用户消费者应用程序,那么我会说数据库。我有一个使用文件系统的DVD管理应用程序(在Program Files中),它是一个备份的PIA。我希望他们每次都将它们存储在数据库中,让我选择保存该文件的位置。
对于更大的商业应用,我会开始改变我的想法。我曾经为一家开发县文员信息管理应用程序的公司工作。我们会根据县指定的仪器编号,以编码格式[处理大量文件的FS问题]将图像存储在磁盘上。这在另一个方面很有用,因为图像可能存在于DB记录之前(由于它们的工作流程)。
与大多数事情一样:'这取决于你在做什么'
答案 48 :(得分:0)
将图像存储在文件系统中的另一个好处是,您无需执行任何特殊操作即可让客户端缓存它们...
...除非图像无法通过文档根目录访问(例如身份验证屏障),在这种情况下,您需要检查代码发送的缓存控制头。
答案 49 :(得分:0)
我更喜欢在数据库中存储图像路径,在文件系统上存储图像(在服务器之间使用rsync以保持一切合理的当前状态)。
然而,我所做的一些内容管理系统的东西需要CMS中的图像,原因有多种 - 可见性控制(因此资产在新闻稿发布之前就被阻止),版本控制,重新格式化(一些CMS的意愿)为缩略图动态调整大小以及将图像链接到WYSIWYG页面的易用性。
因此,对我而言,经验法则是始终将应用程序存储在文件系统上,除非它是由CMS驱动的。
答案 50 :(得分:-1)
不,由于页面拆分。你实际上定义的行数可以是1KB-n MB,因此你的数据库的页面中会有很多空格,这对性能有害。
答案 51 :(得分:-1)
如果您计划面向公众的网站,那么您不应该使用任何一个选项。您应该使用内容分发网络(CDN)。在通过互联网提供大量静态内容时,CDN具有价格,可扩展性和速度优势。
答案 52 :(得分:-1)
文件存储上的图像是最好的选择,并将元数据存储在数据库中作为补充。从Web服务器的角度来看,提供服务的快速方法是直接指向它。如果它在数据库中 - ala Sharepoint - 你有ADO.Net的开销来将它拉出来,流式传输等等。
Documentum - 虽然臃肿而复杂 - 但它的正确之处在于文件在共享上,可用于确定如何存储它们 - 磁盘在服务器,SAN,NAS等等。 Documentum策略是通过根据数据库中的主键对文件夹和文件名进行编码来将文件存储为树结构。数据库成为了解哪些文件是什么以及用于实施安全性的资源。对于大批量系统,这种方法是一种很好的方法。
在处理元数据时也要考虑这一点:如果您需要更新元数据语料库的属性,那么数据库就是您的朋友,因为您可以使用SQL快速执行更新。使用其他标记系统,您手头没有简单的数据处理工具
答案 53 :(得分:-1)
我会采用文件系统方法。正如其他一些人所指出的那样,大多数Web服务器都是为了从文件路径发送图像而构建的。如果您不必从数据库中写入或流出BLOB字段,您将获得更高的性能。为图像提供文件系统存储可以在内容不变或您想要限制数据库负载时更轻松地设置静态页面。
答案 54 :(得分:-1)
在我的小应用程序中,我有至少一百万个文件,最后一次计数约为200GB。所有文件都位于通过iscsi安装在linux服务器上的XFS文件系统中。路径存储在数据库中。对文件路径和文件名使用某种智能命名约定。
恕我直言,使用文件系统来实现它的目的 - 存储文件。在存储二进制数据时,数据库通常不会为标准文件系统提供任何优势。
答案 55 :(得分:-1)
在我目前的申请中,我正在做两件事。当用户识别要附加到记录的图像时,我使用ImageMagick将其调整为适当的大小以便在屏幕上显示(对于我的应用程序大约300x300)并将其存储在数据库中以便于访问,但随后也复制用户的原始文件到网络共享,以便它可用于需要更高分辨率的应用程序(如打印)。
(还涉及其他几个因素:Navision只会显示BMP,因此当我调整大小时,我也会转换为BMP进行存储,并将数据库复制到远程站点,以便能够显示打印只在总公司进行,所以我不需要复制原始文件。)