Storing Images in DB - Yea or Nay?因此,我正在使用一个将图像大量存储在数据库中的应用程序。 您对此有何看法? 我更喜欢将位置存储在文件系统中,而不是直接将其存储在数据库中。 您认为优点/缺点是什么? 我负责管理许多TB图像的一些应用程序。我们发现最好将文件路径存储在数据库中。 有几个问题:
与大多数问题一样,它并不像听起来那样简单。在某些情况下,将图像存储在数据库中是有意义的。
另一方面,存在相关的问题
文件存储。 Facebook工程师对此进行了精彩的演讲。一个收获是知道目录中文件的实际限制。 大海捞针:有效存储数十亿张照片 这可能会花费很多时间,但是如果您正在使用SQL Server 2008(或打算使用SQL Server 2008),建议您查看一下新的FileStream数据类型。 FileStream解决了将文件存储在DB中的大多数问题: 但是,SQL的"透明数据加密"不会加密FileStream对象,因此,如果考虑到这一点,最好将它们存储为varbinary。 从MSDN文章:
数据库中的文件路径绝对是必经之路-我听到一个接一个的故事,有TB图像的客户说,试图在DB中存储任何数量的图像成为一场噩梦-仅性能方面的打击就太大了。 以我的经验,有时最简单的解决方案是根据主键命名图像。因此,很容易找到属于特定记录的图像,反之亦然。但是同时,您不会在数据库中存储有关图像的任何内容。 这里的诀窍是不要成为狂热分子。 这里要注意的一件事是,亲文件系统阵营中没有人列出特定的文件系统。这是否意味着从FAT16到ZFS的所有内容都能轻松击败每个数据库? 没有。 事实是,即使我们只在谈论原始速度,许多数据库也击败了许多文件系统。 正确的做法是为您的精确方案做出正确的决定,并且要这样做,您将需要一些数字和一些用例估计。 在必须保证引用完整性和ACID兼容性的地方,需要将图像存储在数据库中。 您不能交易保证图像和存储在数据库中的图像相关的元数据引用相同的文件。换句话说,不可能保证文件系统上的文件仅在与元数据相同的时间和相同的事务中进行更改。 正如其他人所说,SQL 2008带有Filestream类型,该类型允许您将文件名或标识符作为指针存储在db中,并自动将映像存储在文件系统中,这是一个很好的方案。 如果您使用的是较旧的数据库,那么我想说的是,如果您将其存储为Blob数据,那么您实际上不会从搜索特征的方式中从数据库中获取任何东西,因此这可能是最好的在文件系统上存储地址,并以这种方式存储映像。 这样,您还可以节省文件系统上的空间,因为您将只节省确切的空间量,甚至节省文件系统上的压缩空间。 同样,您可以决定保存一些结构或元素,以使您可以浏览文件系统中的原始图像而没有任何数据库点击,或将文件批量传输到另一个系统,硬盘驱动器,S3或其他情况下-更新其中的位置您的程序,但保持结构,再次尝试增加存储量时,尝试将图像从数据库中取出来并没有太大的影响。 可能还会允许您根据常用的图片网址将一些缓存元素放入Web引擎/程序中,因此也可以将自己保存在那里。 小型静态图像(不超过几个兆)不经常编辑,应存储在数据库中。此方法具有以下优点:易于移植(图像与数据库一起传输),易于备份/还原(图像与数据库备份)和更好的可伸缩性(包含数千个小缩略图文件的文件系统文件夹听起来像是可伸缩性的噩梦)我)。 从数据库提供图像很容易,只需实现一个http处理程序即可,该处理程序将从DB服务器返回的字节数组作为二进制流提供服务。 这是有关该主题的有趣的白皮书。 到BLOB或不到BLOB:数据库或文件系统中的大对象存储 答案是"视情况而定"。当然,这将取决于数据库服务器及其Blob存储方法。它还取决于存储在Blob中的数据类型,以及如何访问该数据。 使用数据库作为存储机制,可以有效地存储和传送较小尺寸的文件。较大的文件可能最好使用文件系统来存储,尤其是如果它们经常被修改/更新时。 (斑点分散成为性能问题。) 还有一点要牢记。支持使用数据库存储Blob的原因之一是ACID合规性。但是,测试人员在白皮书中使用的方法(SQL Server的"大容量日志记录"选项)使SQL Server的吞吐量增加了一倍,有效地将ACID中的" D"更改为" d",因为未使用Blob数据记录事务的初始写入。因此,如果完全ACID合规性是您系统的重要要求,则在将文件I / O与数据库Blob I / O进行比较时,将数据库写入的SQL Server吞吐量数据减半。 我尚未见任何人提及的一件事,但绝对值得注意的是,在大多数文件系统中存储大量图像也存在一些问题。例如,如果您采用上述方法,并以主键命名每个图像文件,那么在大多数文件系统上,如果您尝试将所有图像都放置在一个大目录中,那么一旦您获得了大量图像,就会遇到问题(例如数十万或数百万)。 一种常见的解决方案是将它们散列到平衡的子目录树中。 没有人提到过,数据库保证原子动作,事务完整性和并发性。即使是文件系统,参照完整性也无法显示-那么您如何知道文件名确实仍然正确? 如果您将图像保存在文件系统中,并且在编写新版本甚至删除文件时有人正在读取文件-会发生什么? 我们使用Blob是因为它们也更易于管理(备份,复制,传输)。他们为我们运作良好。 仅将图像的文件路径存储在数据库中的问题是不再可以强制数据库的完整性。 如果文件路径指向的实际映像不可用,则数据库会不经意间出现完整性错误。 鉴于这些图片是所追求的实际数据,并且可以在一个集成数据库中更轻松地进行管理(这些图片不会突然消失),而不必与某种文件系统进行交互(如果文件系统是独立访问的,图像可能突然"消失"),我将其直接存储为BLOB等。 在我曾经工作过的一家公司中,我们在Oracle 8i(当时为9i)数据库中存储了1.55亿张图像。价值7.5TB。 通常,我坚决反对采用最昂贵,最难扩展的部分基础架构(数据库)并将所有负载放入其中。另一方面:它极大地简化了备份策略,尤其是当您有多个Web服务器并且需要以某种方式保持数据同步时。 像大多数其他事情一样,这取决于预期的规模和预算。 我们已经实现了文档成像系统,该系统将所有图像存储在SQL2005 blob字段中。目前有数百GB,我们看到响应时间极好,性能几乎没有下降。此外,为了符合法规要求,我们还有一个中间件层,可将新发布的文档存档到光学自动点唱机系统,该系统将其公开为标准NTFS文件系统。 我们对结果感到非常满意,尤其是在以下方面: 如果这是基于Web的应用程序,则将图像存储在第三方存储交付网络(例如Amazon的S3或Nirvanix平台)上可能会有优势。 假设:应用程序已启用网络/基于网络 令我惊讶的是,没有人真正提到过这个问题……将其委托给其他专家->使用第三方照片/文件托管服务提供商。 将文件存储在付费在线服务上,例如
另一个StackOverflow线程在这里谈论这个问题。 该线程说明了为什么您应该使用第三方托管服务提供商。 非常值得。他们有效地存储了它。没有带宽从您的服务器上传到客户端请求等。 如果您不在SQL Server 2008上,并且有一些可靠的理由将特定的图像文件放入数据库中,则可以采用"两种"方法,并将文件系统用作临时缓存,并将数据库用作主存储库。 例如,您的业务逻辑可以在提供图像文件之前检查磁盘上是否存在图像文件,并在必要时从数据库中检索。这为您提供了多个Web服务器的功能,并减少了同步问题。 SQL Server 2008提供了一种兼具两全其美的解决方案:文件流数据类型。 像常规表一样对其进行管理,并具有文件系统的性能。 这取决于要存储的图像数量及其大小。我过去曾使用数据库来存储图像,并且我的经验还不错。 IMO,使用数据库存储图像的优点是
答:您不需要FS结构来保存图像 如果您的映像很小(例如<64k),并且数据库的存储引擎支持内联(记录中)BLOB,则由于不需要进行间接调用,因此可以进一步提高性能(实现了引用局部性)。 当您处理少量的大尺寸图像时,存储图像可能不是一个好主意。将图像存储在db中的另一个问题是,创建,修改日期等元数据必须由您的应用程序处理。 我最近创建了一个PHP / MySQL应用程序,该程序将PDF / Word文件存储在MySQL表中(到目前为止每个文件最大40MB)。 优点:
缺点:
我将我的实施称为成功,它可以处理备份要求并简化项目的布局。对于使用该应用程序的20至30个人而言,该性能很好。 我不确定这是多少"真实世界"示例,但是我目前有一个应用程序可以存储交易卡游戏的详细信息,包括卡的图像。迄今为止,数据库的记录数仅为2851条,但是考虑到某些卡片已被多次释放并具有备用图稿,因此按尺寸扫描图稿的"主要方块"实际上是更有效的,然后进行动态扫描根据要求生成卡的边框和其他效果。 该图像库的原始创建者创建了一个数据访问类,该类根据请求来呈现图像,并且它非常快速地进行查看和显示单个卡片。 这也简化了发行新卡时的部署/更新,而不是将整个图像文件夹压缩并通过管道发送并确保创建正确的文件夹结构,而是简单地更新数据库并让用户再次下载。目前,该文件的大小最大为56MB,这不是很好,但我正在为将来的发行版开发增量更新功能。此外,该应用程序有一个"无图像"版本,允许那些通过拨号方式获得应用程序的用户不会下载延迟。 迄今为止,该解决方案已经非常有效,因为应用程序本身的目标是在桌面上作为单个实例。有一个网站将所有这些数据存档以供联机访问,但是我绝不会使用相同的解决方案。我同意最好使用文件访问权限,因为它可以更好地扩展对图像的请求频率和数量。 希望这不会太ba,但我看到了这个话题,并希望从相对成功的中小型应用程序中提供一些见解。 以我的经验,我必须管理两种情况:存储在数据库中的图像和存储在db中的文件系统上的图像。 第一种解决方案是数据库中的图像,在某种程度上来说"更干净",因为您的数据访问层将只需要处理数据库对象。但这仅在您必须处理少量数字时才有用。 显然,当您处理二进制大对象时,数据库访问性能会下降,并且数据库尺寸将增长很多,从而再次导致性能损失……并且通常数据库空间比文件系统空间要昂贵得多。 另一方面,在文件系统中存储较大的二进制对象将导致您具有必须同时考虑数据库和文件系统的备份计划,这对于某些系统可能是个问题。 选择文件系统的另一个原因是,当您必须通过第三方访问权限共享图像数据(或声音,视频等)时:目前,我正在开发一个Web应用程序,该应用程序必须使用必须从"外部"访问的图像我的Web场以一种根本不可能访问数据库以检索二进制数据的方式。因此,有时也有一些设计注意事项将促使您做出选择。 在做出选择时,还请考虑一下,如果在访问二进制对象时必须处理权限和身份验证:当将数据存储在db中时,通常可以较容易地解决这些要求。 我曾经从事图像处理应用程序的工作。我们将上传的图像存储在/ images / [今天的日期] / [id号]之类的目录中。但是,我们还从图像中提取了元数据(exif数据),并将其与时间戳等一起存储在数据库中。 在上一个项目中,我将图像存储在文件系统上,这导致备份,复制和文件系统与数据库不同步的麻烦。 在我的最新项目中,我将图像存储在数据库中,并将其缓存在文件系统中,并且效果很好。到目前为止,我还没有遇到任何问题。 其次是关于文件路径的建议。我参与了一些项目,这些项目需要管理大量资产,并且任何直接将内容存储在数据库中的尝试都会导致长期的痛苦和沮丧。 关于将它们存储在数据库中,我可以想到的唯一真正的"专业人士"是轻松实现单个图像资产的潜力。如果没有要使用的文件路径,并且所有图像都直接从数据库中流式传输,则不会有用户发现他们不应访问的文件的危险。 不过,似乎可以通过中间脚本从无法访问Web的文件存储中提取数据来更好地解决。因此,数据库存储并不是真正必要的。 众所周知,除非您是数据库供应商,试图证明您的数据库可以做到(例如,微软吹嘘Terraserver在SQL Server中存储数十亿个图像),否则这不是一个好主意。当替代方案-将图像存储在文件服务器上以及数据库中的路径变得如此简单时,为什么要麻烦呢? Blob字段有点像SUV的越野功能-大多数人不使用它们,那些通常会遇到麻烦的人,然后有些人却遇到了麻烦,但这只是出于乐趣。 将图像存储在数据库中仍然意味着图像数据最终位于文件系统中的某个位置,但是被遮盖了,因此您无法直接访问它。 + ves:
-ves:
两种方法都是通用且已实践的。看一下优点和缺点。无论哪种方式,您都必须考虑如何克服这些缺点。存储在数据库中通常意味着调整数据库参数并实现某种缓存。使用文件系统要求您找到某种使文件系统+数据库保持同步的方法。 我是企业文档管理系统的首席开发人员,其中一些客户存储了数百GB的文档。在不远的将来将达到TB级。出于本页提到的许多原因,我们使用文件系统方法,还有另一个原因:归档。 我们的许多客户必须遵守特定于行业的存档规则,例如存储到光盘或以非专有格式存储。此外,您还可以灵活地向NAS设备添加更多磁盘。如果将文件存储在数据库中,即使使用SQL Server 2008的文件流数据类型,归档选项也变得非常狭窄。 我会亲自将大数据存储在数据库之外。
优点:请将所有内容存储在一个中,轻松访问数据文件,轻松浏览 您的网络服务器(我假设您使用的是服务器)旨在处理图像,而数据库则不是。因此,我将在反对方面投反对票。 仅将路径(可能还有文件信息)存储在数据库中。 如果您需要在文件系统上存储大量图像,则需要考虑以下几点:
正如有人已经提到的,"取决于"。如果数据库中的存储被认为是文件系统的一对一替代,那么它可能不是最佳选择。 但是,如果数据库后端将提供附加值,不仅是blob的序列化和存储,那么它可能是很有意义的。 您可以看一下WKT Raster,它是一个旨在在PostGIS中开发栅格支持的项目,而后者又是PostgreSQL数据库系统的地理空间扩展。 WKT Raster背后的想法不仅是为栅格序列化和存储(使用PostgreSQL系统)定义格式,而且比存储更重要的是,指定可从SQL访问的数据库侧有效图像处理。简而言之,其想法是将操作重心从客户端转移到数据库后端,因此它的位置应尽可能靠近存储本身。 WKT Raster(称为PostGIS)专用于特定领域GIS的应用。 有关更完整的概述,请查看系统的网站和演示文稿(PDF)。 我们将图像存储在表中的唯一原因是因为每个表(或每个工作范围的表集)都是临时的,并在工作流结束时被删除。如果有任何长期存储方式,我们肯定会选择存储文件路径。 还应该注意,我们在内部使用客户端/服务器应用程序,因此无需担心Web界面。 我几乎永远不会将它们存储在数据库中。最好的方法通常是将映像存储在由中央配置变量控制的路径中,并根据DB表和主键(如果可能)命名映像。这给您带来以下优点:
数据数据库 文件的文件系统 我会采用文件系统方法,主要是因为它具有更好的灵活性。考虑一下,如果图像数量变得巨大,则一个数据库可能无法处理它。使用文件系统,假设您使用的是NFS或kind,则可以简单地添加更多文件服务器。 文件系统方法的另一个优点是能够做一些花哨的东西,例如您可以将Amazon S3用作主存储(在数据库中保存url而不是文件路径)。如果S3发生中断,您将退回到文件服务器(可能是另一个包含文件路径的数据库条目)。一些伏都教适用于Apache或您正在使用的任何Web服务器。 将图像存储在文件系统中的另一个好处是,您无需做任何特殊的事情即可让客户端缓存它们。 ...除非当然不能通过文档根目录访问该图像(例如,身份验证屏障),在这种情况下,您需要检查代码正在发送的缓存控制标头。 对于大量的小图像,数据库可能会更好。 我有一个带有许多小缩略图(每个2Kb)的应用程序。当我将它们放在文件系统上时,由于文件系统的块大小,它们各自消耗了8kb。空间增加400%!
有关块大小的更多信息,请参见这篇文章: 您需要记住的一件事是数据集的大小。我相信Dillie-O是唯一一个遥不可及的人。 如果您有一个小型的单用户消费类应用程序,那么我会说DB。我有一个使用文件系统(在那个时候在Program Files中)的DVD管理应用程序,它是要备份的PIA。我希望他们每次都将它们存储在数据库中,让我选择将文件保存在何处。 对于更大的商业应用,我将开始改变想法。我曾经在一家开发县职员信息管理应用程序的公司工作。我们将根据县分配的仪器编号,以编码格式将图像存储在磁盘上,以处理大量文件的FS问题。这在另一个方面很有用,因为该图像可能早于数据库记录就存在(由于其工作流程)。 与大多数事情一样:"这取决于您在做什么" 我曾经使用过许多数字存储系统,它们都将数字对象存储在文件系统上。他们倾向于使用分支方法,因此文件系统上通常会有一个归档树,通常从输入年份开始,例如2009,子目录将是月份,例如8月8日,下一个目录将是日期,例如11,有时它们也会使用小时,然后将使用记录的持久ID来命名文件。使用BLOBS有其优势,我听说它经常在化工行业的IT部门中用于存储成千上万张照片和图表。它可以提供更精细的安全性,单一的备份方法,潜在的更好的数据完整性和改进的跨媒体搜索,Oracle在其用于调用Intermedia的程序包中具有许多此功能(我认为现在称为其他功能)。文件系统还可以具有通过XACML或其他XML类型的安全对象之类的系统提供的精细安全性。有关示例,请参见Fedora对象库的D空间。 我会采用文件系统方法。无需使用映像创建或维护数据库,从长远来看,它将为您节省一些头疼的问题。 尝试使用SQL模仿文件系统通常是一个错误的计划。如果您坚持使用文件系统进行外部存储,最终可以编写更少的代码,从而获得相同或更好的结果。 我更喜欢将图像路径存储在数据库中,并将图像存储在文件系统中(在服务器之间使用rsync来使所有内容保持最新状态)。 但是,出于某些原因,我所做的某些内容管理系统工作需要CMS中的图像-可见性控制(因此资产将保留到新闻稿发布之前),版本控制,重新格式化(某些CMS会针对以下内容进行动态调整大小)缩略图)和易于使用的图像链接到所见即所得页面。 因此,根据我的经验,除非应用程序由CMS驱动,否则始终将其存储在文件系统中。 通过网络将大量二进制数据从数据库中拉出将导致巨大的延迟问题,并且无法很好地扩展。 将路径存储在数据库中,让您的Web服务器承担负载-这就是它的设计目的! 我将使用两种解决方案,我的意思是……我将开发一个litle组件(EJB),该组件将图像存储在DB中以及该图像到服务器的路径。仅当我们拥有新图像或已更新的原始图像时,才会更新该数据库。然后,我还将路径存储在业务数据库中。 从应用程序的角度来看,我将始终使用文件系统(从业务数据库中检索路径),这样我们将解决备份问题,并避免可能的性能问题。 唯一的缺点是我们将相同的图像存储2次...好处是内存便宜,加油! 当然是文件系统。然后,您可以使用所有操作系统功能来处理这些图像-备份,Web服务器,甚至只是使用诸如imagemagic之类的工具编写批处理更改脚本。如果将它们存储在数据库中,则需要编写自己的代码来解决这些问题。 如果您使用的是Teradata,则Teradata Developer Exchange上有关于加载和检索lob和blob的详细文章。 http://developer.teradata.com/applications/articles/large-objects-part-1-loading 如果您正在计划一个面向公众的网站,则不应选择任何一种。您应该使用内容传送网络(CDN)。当通过Internet传递大量静态内容时,CDN具有价格,可伸缩性和速度优势。 我会采用文件系统方法。正如其他一些人所指出的那样,大多数Web服务器都构建为从文件路径发送图像。如果您不必从数据库中写入或流出BLOB字段,则性能将更高。当内容没有更改或您想限制数据库的负载时,具有用于图像的文件系统存储可以更轻松地设置静态页面。 在我的小应用程序中,我至少有100万个文件,最后一次计数约为200GB。所有文件都位于通过iscsi安装在linux服务器上的XFS文件系统中。路径存储在数据库中。对文件路径和文件名使用某种智能命名约定。 恕我直言,使用文件系统来完成它的用途-存储文件。在存储二进制数据方面,数据库通常不会比标准文件系统提供任何优势。 在我当前的应用程序中,我两者都在做。当用户识别出要附加到记录中的图像时,我使用ImageMagick将其调整为适当大小以在屏幕上显示(对于我的应用程序约为300x300),并将其存储在数据库中以便于访问,但同时还要复制用户的原始文件添加到网络共享中,以便可用于需要更高分辨率(例如打印)的应用程序。 (还涉及其他几个因素:Navision仅会显示BMP,因此,当我调整BMP的大小时,我还将转换为BMP进行存储,并且数据库被复制到远程站点,这对于显示图像很有用。打印仅在总部完成,因此我不需要复制原始文件。) 否,由于页面拆分。实际上,您要定义的行可以是1KB-n MB,因此数据库的页面中将有很多空白,这对性能不利。 文件存储上的图像是最好的选择,并通过将元数据存储在数据库中来补充这一点。从Web服务器的角度来看,提供内容的快速方法是直接指向它。如果它在数据库中-ala Sharepoint-您需要ADO.Net的开销才能将其拉出,流式传输等 Documentum虽然while肿且复杂,但它的正确性在于文件已在共享中释放,可供您确定如何存储它们-服务器,SAN,NAS等上的磁盘。 Documentum策略是通过根据数据库中的主键对文件夹和文件名进行编码来将文件存储为树结构。 DB成为了解什么文件是什么以及加强安全性的资源。对于大容量系统,这种方法是一种不错的方法。 在处理元数据时,也要考虑这一点:如果您需要更新元数据语料库的属性,则DB是您的朋友,因为您可以使用SQL快速执行更新。对于其他标记系统,您手边没有便捷的数据处理工具 |