因此,我正在使用一个将图像大量存储在数据库中的应用程序。您对此有何看法?我更喜欢将位置存储在文件系统中,而不是直接将其存储在数据库中。
您认为优点/缺点是什么?
因此,我正在使用一个将图像大量存储在数据库中的应用程序。您对此有何看法?我更喜欢将位置存储在文件系统中,而不是直接将其存储在数据库中。
您认为优点/缺点是什么?
Answers:
我负责管理许多TB图像的一些应用程序。我们发现最好将文件路径存储在数据库中。
有几个问题:
与大多数问题一样,它并不像听起来那样简单。在某些情况下,将图像存储在数据库中是有意义的。
另一方面,存在相关的问题
这可能会花费很多时间,但是如果您正在使用(或计划使用)SQL Server 2008,我建议您看看新的FileStream数据类型。
FileStream解决了将文件存储在DB中的大多数问题:
但是,SQL的“透明数据加密”不会对FileStream对象进行加密,因此,如果考虑到这一点,最好将它们存储为varbinary。
从MSDN文章:
Transact-SQL语句可以插入,更新,查询,搜索和备份FILESTREAM数据。Win32文件系统接口提供对数据的流式访问。
FILESTREAM使用NT系统缓存来缓存文件数据。这有助于减少FILESTREAM数据可能对数据库引擎性能产生的任何影响。不使用SQL Server缓冲池;因此,该内存可用于查询处理。
数据库中的文件路径绝对是必经之路-我听到一个接一个的故事,有TB图像的客户说,试图在DB中存储任何数量的图像成为一场噩梦-仅性能方面的影响就太大了。
以我的经验,有时最简单的解决方案是根据主键命名图像。因此,很容易找到属于特定记录的图像,反之亦然。但是同时,您不会在数据库中存储有关图像的任何内容。
在必须保证引用完整性和ACID兼容性的地方,需要将图像存储在数据库中。
您不能交易保证图像和存储在数据库中的图像相关的元数据引用相同的文件。换句话说,不可能保证文件系统上的文件仅与元数据同时在同一事务中进行更改。
正如其他人所说,SQL 2008带有Filestream类型,该类型允许您将文件名或标识符作为指针存储在db中,并自动将映像存储在文件系统中,这是一个很好的方案。
如果您使用的是较旧的数据库,那么我想说的是,如果将其存储为Blob数据,那么您实际上不会从搜索功能中从数据库中获取任何东西,因此,最好是在文件系统上存储地址,并以这种方式存储映像。
这样,您还可以节省文件系统上的空间,因为您将只节省确切的空间量,甚至节省文件系统上的压缩空间。
另外,您可以决定保存一些结构或元素,以使您能够浏览文件系统中的原始图像而没有任何数据库命中,或将文件批量传输到另一个系统,硬盘驱动器,S3或另一个方案中-更新其中的位置您的程序,但保持结构,再次尝试增加存储量时,尝试将图像从数据库中取出来并没有太大的影响。
可能还会允许您根据常用的图像URL向Web引擎/程序中添加一些缓存元素,因此您也可以将自己保存在那里。
不经常编辑的小型静态图像(不超过几个兆)应存储在数据库中。此方法具有以下优点:易于移植(通过数据库传输图像),更容易备份/还原(通过数据库备份图像)和更好的可伸缩性(带有数千个小缩略图文件的文件系统文件夹听起来像是可伸缩性的噩梦)我)。
从数据库提供图像很容易,只需实现一个http处理程序,该处理程序将从DB服务器返回的字节数组作为二进制流提供服务。
这是有关该主题的有趣的白皮书。
答案是“视情况而定”。当然,这将取决于数据库服务器及其Blob存储方法。它还取决于存储在Blob中的数据类型,以及如何访问该数据。
使用数据库作为存储机制,可以有效地存储和传送较小尺寸的文件。较大的文件可能最好使用文件系统来存储,尤其是如果它们经常被修改/更新时。(斑点分散成为性能问题。)
还有一点要牢记。支持使用数据库存储Blob的原因之一是ACID合规性。但是,测试人员在白皮书中使用的方法(SQL Server的“大容量日志记录”选项)使SQL Server的吞吐量增加了一倍,有效地将ACID中的“ D”更改为“ d”,因为未使用Blob数据记录事务的初始写入。因此,如果完全ACID合规性是您系统的重要要求,则在将文件I / O与数据库Blob I / O进行比较时,将数据库写入的SQL Server吞吐量数据减半。
我尚未见任何人提及的一件事,但绝对值得注意的是,在大多数文件系统中存储大量图像也存在一些问题。例如,如果您采用上述方法,并以主键命名每个图像文件,那么在大多数文件系统上,如果您将所有图像都放置在一个很大的目录中,一旦尝试将所有图像放置在一个大目录中,就会遇到问题(例如数十万或数百万)。
一种常见的解决方案是将它们散列到平衡的子目录树中。
没有人提到过,数据库保证原子动作,事务完整性和并发性。即使是文件系统,参照完整性也无法显示-那么您如何知道您的文件名确实仍然正确?
如果您将图像保存在文件系统中,并且在编写新版本甚至删除文件时有人正在读取文件-会发生什么?
我们使用Blob是因为它们也更易于管理(备份,复制,传输)。他们为我们运作良好。
在我曾经工作过的一家公司中,我们在Oracle 8i(当时为9i)数据库中存储了1.55亿张图像。价值7.5TB。
如果您不在SQL Server 2008上,并且有一些充分的理由将特定的图像文件放入数据库中,则可以采用“两种”方法,并将文件系统用作临时缓存,并将数据库用作主存储库。
例如,您的业务逻辑可以在提供图像文件之前检查磁盘上是否存在图像文件,并在必要时从数据库中检索。这为您提供了多个Web服务器的功能,并减少了同步问题。
我不确定这是多少“真实世界”示例,但是我目前有一个应用程序可以存储交易卡游戏的详细信息,包括卡的图像。迄今为止,数据库的记录数仅为2851条,但是考虑到某些卡片已被多次释放并具有备用图稿,因此在尺寸上扫描图稿的“主要方块”然后动态地进行扫描实际上更为有效。根据要求生成卡的边框和其他效果。
该图像库的原始创建者创建了一个数据访问类,该类根据请求渲染图像,并且可以非常快速地查看和使用单个卡。
这也简化了发行新卡时的部署/更新,而不是将整个图像文件夹压缩并通过管道发送并确保创建正确的文件夹结构,而是简单地更新数据库并让用户再次下载。目前,该文件的大小最大为56MB,这不是很好,但我正在为将来的发行版开发增量更新功能。此外,该应用程序有一个“无图像”版本,允许那些通过拨号方式获得应用程序的用户不会下载延迟。
迄今为止,该解决方案一直非常有效,因为应用程序本身的目标是在桌面上作为单个实例。有一个网站将所有这些数据存档以供联机访问,但是我绝不会使用相同的解决方案。我同意最好使用文件访问权限,因为它可以更好地扩展对图像的请求的频率和数量。
希望这不会太ba,但我看到了这个话题,并希望从相对成功的中小型应用程序中提供一些见解。
SQL Server 2008提供了一个兼具两全其美的解决方案:文件流数据类型。
像常规表一样对其进行管理,并具有文件系统的性能。
这取决于要存储的图像数量及其大小。我过去曾使用数据库来存储图像,并且我的经验还不错。
IMO,使用数据库存储图像的优点是
A.不需要FS结构来保存图像
B.当要存储更多项目时,数据库索引的性能比FS树更好
。C.智能调优的数据库在缓存查询结果方面表现出色
D.备份很简单。如果已设置复制并且内容是从附近的服务器传递的,则此方法也很好用。在这种情况下,不需要显式同步。
如果您的映像很小(例如<64k),并且数据库的存储引擎支持内联(记录中)BLOB,则由于不需要进行间接调用,因此可以进一步提高性能(实现了引用的局部性)。
当您处理少量的大尺寸图像时,存储图像可能不是一个好主意。在db中存储图像的另一个问题是,创建,修改日期等元数据必须由您的应用程序处理。
我最近创建了一个PHP / MySQL应用程序,该程序将PDF / Word文件存储在MySQL表中(到目前为止,每个文件最大40MB)。
优点:
缺点:
我将我的实施称为成功,它可以满足备份要求并简化项目的布局。对于使用该应用程序的20至30个人而言,该性能很好。
以我的经验,我必须管理两种情况:存储在数据库中的图像和存储在db中的文件系统上的图像。
第一种解决方案是数据库中的图像,它在某种程度上“更干净”,因为您的数据访问层将只需要处理数据库对象。但这仅在您必须处理少量数字时才有用。
显然,当您处理二进制大对象时,数据库访问性能正在下降,并且数据库尺寸将增长很多,从而再次导致性能损失……并且通常数据库空间比文件系统空间昂贵得多。
另一方面,在文件系统中存储较大的二进制对象将导致您具有必须同时考虑数据库和文件系统的备份计划,这对于某些系统可能是个问题。
选择文件系统的另一个原因是,当您必须通过第三方访问权限共享图像数据(或声音,视频等)时:目前,我正在开发一个Web应用程序,该应用程序使用必须从“外部”访问的图像我的Web场以一种根本不可能访问数据库以检索二进制数据的方式。因此,有时也有一些设计注意事项将促使您做出选择。
在做出选择时,还请考虑一下,如果在访问二进制对象时必须处理权限和身份验证:当将数据存储在db中时,通常可以较容易地解决这些要求。
在上一个项目中,我将图像存储在文件系统上,这导致备份,复制和文件系统与数据库不同步的麻烦。
在我的最新项目中,我将图像存储在数据库中,并将其缓存在文件系统中,并且效果很好。到目前为止,我还没有遇到任何问题。