【问题标题】:What is difference between storing data in a blob, vs. storing a pointer to a file?将数据存储在 blob 中与存储指向文件的指针有什么区别?
【发布时间】:2012-11-06 06:37:42
【问题描述】:

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

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

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

【问题讨论】:

    标签: mysql blob sqldatatypes


    【解决方案1】:

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

    BLOB 优势:

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

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

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

    文件优势:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

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

      【讨论】:

        【解决方案3】:

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

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

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

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

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

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

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

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

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

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

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

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

        this post 上更好地讨论了为备份存储 blob 的优势,其中回答的人与我有类似的问题。

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

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

        所以我想说

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

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

        我希望它有所帮助。干杯

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            【解决方案5】:

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

            【讨论】:

            • 并假设他从 windows 服务器更改为 linux。还有更好的指向文件的方法吗?
            • 如果您谈论文件夹分离/或\任何一个简单的sql查询或迁移脚本能够更改所有记录。另外如果是web应用,一般会存储相对路径。
            • 备份一个嵌入了数十或数百 GB 文件的数据库一点也不好玩。使用rsync 轻松备份包含数 TB 数据的文件系统。
            • 除此之外,文件夹和布局会随着操作系统的变化而变化,这使得当它可以简单地通过 mysqldump 解决时,这是一个艰难的过程
            • 您好,感谢您的回复。但我仍然在一个方面感到困惑。如果 blob 包含指向文件位置的指针,这与使用 varchar 将指向文件的指针存储在磁盘上有何不同?抱歉,如果我的问题不清楚,我对硬件方面不太熟悉。
            猜你喜欢
            • 2020-09-28
            • 1970-01-01
            • 2021-01-13
            • 2013-07-28
            • 2021-09-27
            • 2021-06-03
            • 1970-01-01
            • 2014-04-21
            • 1970-01-01
            相关资源
            最近更新 更多