你会将二进制数据存储在数据库还是文件系统?

这是一个以前被问到的问题( 大文本和图像在SQL中 ),但主要是为了将被改变的数据。 在我的情况下,数据将被存储,永远不会改变。 把所有东西放在一起似乎是明智的。

有没有什么原因,我不应该在数据库中存储静态二进制数据?

假设这是明智的做法,将这些数据存储在不同的表中有什么优势吗? (你现在可能开始意识到,我不是一个数据库专家…)

澄清:可能不会超过10-20个用户,但这些将在美国和英国。 二进制数据将不得不在任何情况下被转移。

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

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

存储BLOBS的最大缺点是内存消耗。 你能想象一下,从x中select*会为成千上万的logging带来45k的图像吗?

正如Mehrdad所说,这也有好处。 所以,如果你决定采用这种方法,你应该devise你的数据库,以便大多数查询返回更less的结果,其中包含BLOB数据。 也许例如为此目的build立一对一的关系。

所有这些讨论在表中有一个“select * from table”引起巨大的内存和/或带宽问题时,这是一个没有问题的问题。 所有返回的是指向所讨论的LOB的指针。 没有足够的声望来将评论置于上下文中,但是看这个的人应该知道这不是问题。

我认为这取决于你的build筑物的应用。 如果您正在构build一个CMS系统,并且数据的使用将是在Web浏览器中显示图像,那么将图像保存到磁盘而不是将其放入数据库可能是有意义的。 虽然老实说,我会做这两个,这可能允许服务器添加到农场,而不必复制文件到处。

另一个用例可能是一个复杂的对象,比如一个工作stream,甚至是一个有很多相互依赖的业务对象。 您可以将这两个序列化为二进制或基于文本的格式,并将其保存在数据库中。 那么你可以从DB中获得好处:ATOMIC,Backups等等…

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

从原理的angular度处理这个问题,关系数据库(主要是)存储结构化数据。 如果不能查询条件或join数据元素,它可能不属于数据库。 我没有看到在WHERE子句中使用的图像BLOB,所以我会说保持它在数据库之外。 另一方面,CLOB可以用于查询。

我很熟悉一个相当不错的OSS项目,它在开始时决定将图像存储在MySQL数据库中,而且它被certificate是自那时以来应对的前3个不良想法之一。 (由于“无情地重构”被诅咒加剧了,但这是另一回事。)

这其中造成的严重问题包括:

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

  2. 图像文件失去“文件”。 没有date大小等,除非作为date(需要pipe理代码)存储(冗余)。

  3. 任何字节序列都不能很好地处理,无论是存储还是操作。

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

  5. 脆弱性。 因为整个安排是不自然和敏感的,你不知道接下来会咬什么(有助于反重构的心态)。

好处? 除了当时可能是阻力最小的path之外,我无法想到。

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

简单起见:在我们的例子中,这些附件是从最终用户的浏览器上传的,只需要把它们写到一个目录(在数据库服务器上),然后把它们在SQLpipe道上进行stream式传输就简单了。 在DB中有一个logging,但是DB只包含关于附件的元信息和磁盘上文件的名字(在我们的例子中是一个GUID)

在备份/恢复方面:这些blob可能会成为数据库中最大的一块。 无论何时运行完整备份,您都会一遍又一遍地复制这些数据,即使您知道永远不会改变。 对我们来说,看起来要简单得多(less)很多的备份,并将附件目录的xcopy拷贝到备用服务器上作为备份。

谁有想将图像(或其他二进制文档)存储在数据库中的人不是我很高兴的人。 数据库意味着存储[主要是] INDEXABLE,DISCRETE数据。 不是没有意义的二进制数据的BLOB。 如果你已经用BLOBs来处理二进制数据,那么你已经知道了。

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

这不正是LOB或CLOB或….的devise?

我们使用CLOB存储大型航空公司系统的信用卡交易的大型encryption。

内存消耗是你最大的罪魁祸首。

HTH

干杯,

某些数据库(例如Postgresql)会自动压缩字段,当从数据库直接读取数据时可能会更快。 而且,该程序可以一次读取所有的字段和图像。

这里的性能问题已经在上面解决了,所以我不再重复。 但是,如果你存储的东西很多(如网站上的图片/文档),我认为一个好的提示是build立一个caching系统。

我的意思是把所有的数据存储在你的数据库中,但是当有人请求这个文件时,检查它是否存在于磁盘上(基于一个已知的文件名,在一个临时文件夹中),如果没有,从数据库中抓取并写入该文件夹,然后将其stream式传输给用户。 对于同一个文件的下一个请求,因为它存在于磁盘上,所以可以在不碰到数据库的情况下从服务器上获取。 但是,如果您需要删除这些文件(或者您的networking服务器变成kapput!),那么这些文件就不会在用户请求时再次从数据库中重build。 这应该比从DB提供相同文件的每个请求快得多。