44

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

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

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

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

4

11 回答 11

34

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

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

于 2009-03-19T14:50:34.363 回答
12

当表中包含 LOB 时,所有这些关于执行“从表中选择 *”会导致巨大的内存和/或带宽问题的讨论都不是问题。返回的只是一个指向相关 LOB 的指针。没有足够的声誉将评论放在上下文中,但看到这个的人应该知道这不是问题。

于 2011-06-08T17:44:59.570 回答
9

如果要存储 BLOBS,最大的缺点是内存消耗。你能想象 select * from x 会对每条 45k 图像的数千条记录做什么吗?

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

于 2009-03-19T14:57:46.343 回答
7

我熟悉一个规模相当大的 OSS 项目,该项目一开始就决定将图像存储在 MySQL 数据库中,并且它被证明是他们一直在应对的三大坏主意之一。(“无情地重构”是一种诅咒,但这是另一回事。)

这导致的严重问题包括:

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

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

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

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

  5. 脆弱性。因为整个安排是不自然的和敏感的,你不知道它接下来会咬到哪里(助长了反重构的心态)。

好处?没有我能想到的,除了它可能是当时阻力最小的路径。

于 2009-03-19T16:26:47.773 回答
7

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

于 2010-06-10T12:54:32.530 回答
5

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

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

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

于 2009-03-19T15:09:25.410 回答
4

任何想在数据库中存储图像(或其他二进制文档)的人都不是我很满意的人。数据库用于存储 [主要是?] INDEXABLE、DISCRETE 数据。不是无意义的二进制数据的 BLOB。如果您亲身使用 BLOB 处理二进制数据,那么您已经知道这一点。

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

于 2014-05-02T02:35:56.633 回答
2

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

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

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

高温高压

干杯,

于 2009-03-19T15:01:00.327 回答
2

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

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

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

于 2009-03-19T15:55:40.860 回答
1

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

于 2009-03-19T15:14:03.790 回答
1

这里的性能问题如上所述,所以我不会重复它。但是我认为,如果您要存储大量流出的内容(例如网站上的图像/文档),那么构建缓存系统是一个很好的建议。

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

于 2009-03-19T16:07:48.723 回答