我正在使用一款将图片大量存储在数据库中的应用程序。你对此有何看法?我更倾向于将其位置存储在文件系统中,而不是直接存储在数据库中。
你认为这样做的利弊是什么?
我负责管理一些处理数千GB图像的应用程序,我们发现在数据库中存储文件路径是最佳选择。
但有几个问题:
文件存储。Facebook工程师有一个很棒的讨论,其中一个要点是要了解目录中文件的实际限制。
这可能有点冒险,但如果您正在使用(或计划使用)SQL Server 2008,我建议看一下新的FileStream数据类型。
FileStream解决了大部分在DB中存储文件的问题:
然而,SQL的“透明数据加密”不会加密FileStream对象,因此如果考虑到这一点,最好将它们存储为varbinary。
从MSDN文章中可以了解到:
Transact-SQL语句可以插入、更新、查询、搜索和备份FILESTREAM数据。Win32文件系统接口提供对数据的流式访问。
FILESTREAM使用NT系统缓存来缓存文件数据。这有助于减少FILESTREAM数据对数据库引擎性能的影响。不使用SQL Server缓冲池; 因此,该内存可用于查询处理。
在数据库中使用文件路径绝对是正确的选择 - 我听过很多客户的故事,他们有TB级别的图片需要存储,将这些图片存储在数据库中成为了一场噩梦 - 单单是性能损失就已经太大了。
根据我的经验,有时候最简单的解决方案就是按照主键命名图片。这样很容易找到属于特定记录的图片,反之亦然。但同时,您并未在数据库中存储任何与图片相关的信息。
关键在于不要成为一个狂热者。
值得注意的一点是,文件系统阵营中没有人列出特定的文件系统。这是否意味着从FAT16到ZFS的所有内容都轻松打败了每个数据库?
不是的。
事实上,许多数据库甚至在仅谈论原始速度时也能击败许多文件系统。
正确的做法是为您的精确场景做出正确的决策,并为此,您需要一些数字和一些用例估计。
在必须保证引用完整性和ACID兼容性的地方,将图像存储在数据库中是必需的。
您无法事务性地保证存储在数据库中的图像及其元数据引用同一文件。换句话说,无法保证在文件系统上的文件只会在同一时间和同一事务中与元数据一起更改。
正如其他人所说,SQL 2008带有一种名为Filestream的类型,允许您将文件名或标识符存储为指针在数据库中,并自动将图像存储在文件系统中,这是一个很好的场景。
如果您使用较旧的数据库,则我会建议,如果您将其存储为blob数据,则无法从数据库中获得任何搜索功能,因此最好将地址存储在文件系统上,并以这种方式存储图像。
这样,您还可以节省文件系统上的空间,因为您只需要保存确切的空间量,甚至是压缩后的空间量。
此外,您可以决定使用某些结构或元素保存原始图像,允许您在没有任何数据库访问的情况下浏览文件系统中的原始图像,或者批量传输文件到另一个系统、硬盘驱动器、S3或其他情况——在程序中更新位置,但保持结构,而不需要试图从数据库中提取图像时受到过多影响以增加存储。
可能,这也允许您向基于常见图像url的缓存元素抛一些东西,以便在您的Web引擎/程序中节省自己。
小型静态图片(不超过几兆)且不经常编辑的可存储在数据库中。该方法有多个优点,包括更便于移植(图像随数据库一起传输)、更便于备份/恢复(图像与数据库一起备份)和更好的可扩展性(一个文件系统文件夹有成千上万的缩略图文件听起来像是一个可扩展性的噩梦)。
从数据库提供图像很容易,只需实现一个HTTP处理程序,将从DB服务器返回的字节数组作为二进制流提供即可。