将数据存储在blob中和存储指向文件的指针之间的区别是什么



我有一个关于MySQL中blob数据类型的问题。

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

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

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

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

由于它是一种特定于存储二进制数据的数据类型,因此通常使用它来存储二进制格式的文件,存储图像文件是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列。

我希望它能有所帮助。干杯

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

BLOB优势:

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

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

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

文件优势:

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

  2. 即使数据库并没有一些奇怪的大小限制,和只存储一个文件相比,它在存储BLOB方面总是会有一些开销。此外,如果BLOB很大,一些数据库不提供逐块访问BLOB或stream-it的接口,这可能会对您的工作流程造成很大阻碍。

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

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

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

以下是可能影响您决策的其他几个因素:

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

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

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

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

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

数据库也可能随着大的Blob而快速增长,然后备份等任务就会变慢。我会选择数据库中的一个文件位置和文件系统上的物理存储。

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

最新更新