您会将二进制数据存储在数据库或文件系统中吗?

时间:2009-03-19 14:47:19

标签: database binary-data

这是之前提出的问题(large-text-and-images-in-sql),但主要是针对将要更改的数据。在我的情况下,数据将被存储并且永远不会改变。把所有东西放在一起似乎是明智的。

我不应该将静态二进制数据存储在数据库中吗?

假设这是明智之举,将这些数据存储在单独的表中是否有任何好处? (你可能现在开始意识到我不是数据库专家......)

澄清: 可能会有不超过10-20个用户,但这些用户将在美国和英国。无论如何都必须转移二进制数据。

11 个答案:

答案 0 :(得分:33)

在数据库中存储数据的优势在于利用数据库安全机制并降低维护成本(备份,......)。它的缺点是增加了数据库负载和消耗连接(这对于每个连接的许可数据库服务器来说可能很昂贵)。如果您使用的是SQL Server 2008,FILESTREAM可能是一个不错的选择。

顺便说一下,对于Web应用程序(或任何其他可能需要流式传输数据的应用程序),在数据库外部存储数据通常更为明智。

答案 1 :(得分:11)

所有这些谈论关于做一个“select * from table”导致巨大的内存和/或带宽问题,当表中有一个LOB是没有问题的。返回的所有内容都是指向所讨论的LOB的指针。没有足够的声誉将评论放在上下文中,但看着这个的人应该知道这不是问题。

答案 2 :(得分:9)

如果要存储BLOBS,最大的缺点是内存消耗。 你能想象从x中选择*会对成千上万的记录做什么吗?每个记录都有45k图像?

正如迈赫达德所说,这也有好处。因此,如果您决定采用该方法,则应尝试设计数据库,以便大多数查询返回较少的结果,其中包含BLOB数据。也许例如为此目的建立一对一的关系。

答案 3 :(得分:6)

从原则的角度解决问题,关系数据库(主要)用于存储结构化数据。如果您无法创建查询条件或加入数据元素,则它可能不属于数据库。我没有看到在WHERE子句中使用的图像BLOB,所以我要说它保持在数据库之外。另一方面,CLOB可用于查询。

答案 4 :(得分:5)

我认为这取决于你的建筑应用。如果您正在构建CMS系统,并且数据的使用将在Web浏览器中显示图像,则将图像保存到磁盘而不是放入数据库可能是有意义的。虽然老实说我会同时做到这两点,这可能允许将服务器添加到服务器场而无需在整个地方复制文件。

另一个用例可能是复杂的对象,例如工作流,甚至是具有大量相互依赖性的业务对象。您可以将这两种格式序列化为二进制或基于文本的格式,并将它们保存在数据库中。然后你就可以获得数据库的好处:ATOMIC,备份等......

我认为人们不应该首先使用select *个查询。你所做的是提供两种获取数据的方法,一种方法返回摘要信息,第二种方法返回blob。我无法想象为什么你需要同时返回数以千计的图像。

答案 5 :(得分:5)

我熟悉一个相当大的OSS项目,该项目一开始就决定将图像存储在MySQL数据库中,并且它已被证明是他们从那时起应对的三大坏主意之一。 (“无情地重构”这一事实加剧了这一点,但这是另一个故事。)

这引起的严重问题包括:

  1. 超过最大有效数据库大小(mysql)。 (图像所需的总空间超过所有其他空间至少2个数量级)。

  2. 图像文件失去了“文件性”。没有日期大小等,除非存储(冗余)为日期(需要管理代码)。

  3. 对于存储或操作,任意字节序列都不能很好地处理。

  4. “我们永远不需要从外部访问图像”这是一个危险的假设。

  5. 脆弱性。因为整个安排都是不自然和敏感的,你不知道它会在下一个地方咬人(有助于反重构的心态)。

  6. 好处?没有我能想到的,除非它可能是当时阻力最小的道路。

答案 6 :(得分:3)

任何想要将图像(或其他二进制文档)存储在数据库中的人都不是我非常满意的人。数据库用于存储[大多数?] INDEXABLE,DISCRETE数据。不是无意义的二进制数据的BLOB。如果您亲自使用BLOB获取二进制数据,那么您已经知道了。

您应该在文件系统中存储对该文件的引用。最佳做法是文件名,而不是绝对(甚至相对)路径。

答案 7 :(得分:2)

我们在我们的系统中存储附件,并且您无法更改附件,因此我认为我们在同一页面上具有“将被存储且永不改变”的数据。我们特意决定将存储在数据库中。我们这样做有两个原因,简单性和备份/恢复时间。

简单性:在我们的例子中,这些附件是从最终用户的浏览器上传的,只是将它们写入目录(在数据库服务器上)比将它们沿着SQL管道流式传输更简单。数据库中有它们的记录,但数据库只包含有关附件的元信息,以及磁盘上文件的名称(在我们的例子中为guid)

在备份/恢复方面:这些blob可能会成为数据库中最大的部分之一。无论何时运行完整备份,您都会反复复制这些位,即使您知道也永远无法更改。对我们来说,拥有(更多)较小的备份似乎要简单得多,并且将附件目录的xcopy作为备份执行到辅助服务器。

答案 8 :(得分:1)

这不正是LOB或CLOB或....的设计吗?

我们使用CLOB为主要航空公司系统存储信用卡交易的大型加密。

记忆消耗是你最大的罪魁祸首。

HTH

欢呼声,

答案 9 :(得分:1)

某些数据库(例如Postgresql)会自动压缩字段,也许直接从db读取它们会更快。此外,该程序可以一举读取所有字段和图像。

答案 10 :(得分:1)

这里的性能问题如上所述,所以我不再重复了。但是,如果您要存储将要流式传输的内容(例如网站上的图像/文档),我认为一个很好的提示是在缓存系统中构建。

我的意思是存储数据库中的所有数据,但当有人请求该文件时,检查它是否存在于磁盘上(基于已知的文件名,在临时文件夹中),如果没有,请从数据库中获取它将其写入文件夹,然后将其流式传输给用户。对于对同一文件的下一个请求,由于它存在于磁盘上,因此可以从那里进行服务而无需访问数据库。但是如果你需要删除这些文件(或者你的web服务器变成kapput!),那么无关紧要,因为当人们请求它们时,它们将再次从数据库重建。这应该比为DB中的同一文件提供每个请求快得多。