29

blob我对MySQL 中的数据类型有疑问。

我读到该数据类型可用于存储文件。我还读到另一种方法是将文件存储在磁盘上并包含指向其在数据库中位置的指针(通过 varchar 列)。

但我有点困惑,因为我读过 blob 字段没有存储在行内,需要单独查找来检索其内容。那么这与在文件系统上存储指向文件的指针有什么不同吗?

4

5 回答 5

30

我读到该数据类型可用于存储文件。

根据Blob 上的MySQL 手册页,ABLOB是一个二进制大对象,可以容纳可变数量的数据。

由于它是一种特定于存储二进制数据的数据类型,因此通常使用它来以二进制格式存储文件,存储图像文件在 Web 应用程序中非常常见。

对于 Web 应用程序,这意味着您首先需要将文件转换为二进制格式,然后将其存储,并且每次需要检索文件时,您都需要执行将它们转换回原始格式的相反过程。

除此之外,在您的数据库中存储大量数据可能会减慢它的速度。特别是在不仅仅用于托管数据库的系统中。

我还读到另一种方法是将文件存储在磁盘上并包含指向其在数据库中的位置的指针

牢记以上所有考虑因素,Web 应用程序的常见做法是将文件存储在 MySQL 以外的其他位置,然后简单地将其路径存储在数据库中。在处理大量数据时,这种方法可能会加速您的数据库。

但我有点困惑,因为我读过 blob 字段没有存储在行内,需要单独查找来检索其内容。

实际上,这取决于您使用的存储引擎,因为每个引擎都处理数据并以不同的方式存储它。对于适用于关系数据库的 InnoDB 引擎,您可能需要阅读MySQL 性能博客中关于 blob 如何存储在 MySQL 中的这篇文章。

但抽象地说,在 MySQL 5 及更高版本上,blob 存储如下:

Innodb 将整个 blob 存储在行页面上或仅 20 字节的 BLOB 指针优先存储在页面上的较小列,这是合理的,因为您可以存储更多它们。

所以你现在可能在想,正确的做法是将它们存储为单独的文件,但是使用 blob 存储数据有一些优点,第一个(在我看来)是备份。我管理着一台小型服务器,我不得不创建另一个子例程,只是为了将作为路径存储的文件复制到另一个存储磁盘(我们买不起像样的磁带备份系统)。如果我将我的应用程序设计为使用 blob mysqldump,那么备份整个数据库所需的一切都将是简单的。

在这篇文章中更好地讨论了为备份存储 blob 的优势,其中回答的人遇到了与我类似的问题。

另一个优点是安全性和易于管理权限和访问。MySQL 服务器中的所有数据都受密码保护,您可以轻松地为用户管理权限,了解谁访问什么,谁不访问。

在依赖 MySQL 权限系统进行身份验证和使用的应用程序中。这肯定是一个加分项,因为假设入侵者从您的磁盘或没有访问权限的用户检索图像(或压缩文件之类的二进制文件)会有点困难。

所以我会这么说

如果您要管理 MySQL 和其中的所有数据并且必须定期备份或打算更改甚至考虑将来更改操作系统,并且拥有不错的硬件并针对它优化了 MySQL,请选择 BLOB。

如果您不会管理您的 MySQL(例如在 web 主机中)并且不打算更改操作系统或进行备份,请坚持使用varchar指向您的文件的列。

我希望它有所帮助。干杯

于 2012-11-17T22:38:49.027 回答
12

如果您将数据存储为 BLOB 字段,那么您就是将其作为对象抽象的一部分。

BLOB 优势:

  1. 如果您想删除带有 BLOB 的行,或者将其作为主/从表关系的一部分或整个表层次结构删除,您的 BLOB 将自动处理并且与数据库中的任何其他对象具有相同的生命周期。

  2. 您的脚本不需要访问任何东西,只需访问数据库即可获得所需的一切。在许多情况下,直接文件访问会打开整个蠕虫病毒,了解如何绕过访问或安全限制。例如,通过文件访问,他们可能必须挂载包含实际文件的文件系统。但是使用数据库中的 BLOB,您只需能够连接到数据库,无论您身在何处。

  3. 如果您将其存储在文件中并且文件被替换、删除或不再可访问,您的数据库将永远不会知道 - 实际上,您无法保证完整性。此外,在使用文件时很难可靠地支持多个版本。如果您使用并依赖交易,那几乎是不可能的。

档案优势:

  1. 一些数据库对 BLOB 的处理相当差。例如,虽然 MySQL 中的官方 BLOB 限制为 4GB,但实际上默认配置仅为 1MB。您可以通过调整客户端和服务器配置以增加 MySQL 命令缓冲区来将其增加到 16-32MB,但这在性能和安全性方面还有很多其他影响。

  2. 即使数据库没有一些奇怪的大小限制,与存储文件相比,它在存储 BLOB 方面总是会有一些开销。此外,如果 BLOB 很大,则某些数据库不提供逐个访问 blob 的接口,或者stream它,这可能是您工作流程的一大障碍。

最后,这取决于你。我通常会尝试将其保留在 BLOB 中,除非这会产生不合理的性能问题。

于 2012-11-17T23:15:43.237 回答
7

是的,与行不适合在同一页面中的 MySQL blob 将存储在溢出页面上 请注意,某些 blob 足够小,以至于它们与行的其余部分一起存储,就像任何其他列一样。blob 页面与存储其行的页面不相邻,因此它们可能会导致额外的 I/O 来读取它们。

另一方面,就像任何其他页面类型一样,blob 页面可以占用 InnoDB 缓冲池中的内存,因此即使它们位于单独的页面上,随后读取 blob 也非常快。文件可以由操作系统缓存,但通常是从磁盘读取的。

以下是可能影响您的决定的其他一些因素:

  • Blob 以一行在逻辑上存储。这意味着如果您删除该行,关联的 blob 将被自动删除。但是,如果您将 blob 存储在数据库之外,那么在从数据库中删除行后,您最终会得到孤立的 blob 文件。您必须执行手动步骤来查找和删除这些文件。

  • 存储在行中的 Blob 也遵循事务语义。例如,在您提交之前,新的 blob 或更新的 blob 对其他事务是不可见的。您也可以回滚更改。将 blob 存储在数据库外部的文件中会使这变得更加困难。

  • 当您备份包含 blob 的数据库时,该数据库当然要大得多,但是当您备份时,您可以一步获得所有数据和相关联的 blob。如果在外部存储 blob,则必须备份数据库并备份存储 blob 文件的文件系统。如果您需要确保从某一瞬间捕获数据和 blob,您几乎需要使用某种文件系统快照。

  • 如果使用复制,确保 blob 自动复制到复制从属设备的唯一自动方法是将 blob 存储在数据库中。

于 2012-11-17T23:07:55.167 回答
3

文件系统访问将比通过数据库更快。Blobs 列在索引/排序等方面有一些缺点,如果您希望将来可以使用您的文件名列,您可以这样做。

数据库也可以通过大 blob 快速增长,然后像备份这样的任务变得更慢。我会使用文件系统上的物理存储在数据库中的文件位置。

于 2012-11-17T22:11:44.583 回答
2

更好的方法是将文件存储在文件系统文件夹中,并通过数据库中的 varchar 字段指向它们的路径。在数据库中保存文件的缺点之一是减慢或降低其性能。

于 2012-11-17T22:05:25.583 回答