当前位置: 首页 > 面试题库 >

将base64编码的数据存储为BLOB或TEXT数据类型

魏澄邈
2023-03-14
问题内容

我们有一个MySQL InnoDB表,其中包含约10列由base64编码的小型javascript文件和由base64编码的png(小于2KB大小)图像。

插入的次数很少,但读取次数却很多,但是输出会在Memcached实例缓存几分钟,以避免后续的读取。

现在,我们正在使用BLOB这些列,但是我想知道TEXT在性能或快照备份方面切换到数据类型是否有优势。

我的搜索挖掘表明,BLOBTEXT我的情况接近相同的,因为我不知道前手什么类型的数据实际上将被存储我去了BLOB

您是否有针对此特定案例的TEXT vs BLOB辩论的任何指针?


问题答案:

一个人不应该在自己的数据库中存储Base64编码的数据…

Base64是仅使用可打印文本字符表示任意二进制数据的一种方式:它设计用于需要跨只能处理可打印文本(例如SMTP
/电子邮件)的协议或介质传输此类二进制数据的情况。它增加了数据大小(增加了33%)并增加了编码/解码的计算成本,因此除非绝对必要,否则应避免这样做。

相反,
的全部要点BLOB是它们存储原始二进制字符串
。因此,只需继续将您的资料直接存储到您的BLOB列中,而无需首先对它们进行Base64编码。通常,您需要将相关的元数据存储在其他列中,例如文件版本/上次修改日期,媒体类型和(对于文本文件,例如JavaScript源)字符编码。您可能决定对TEXT文本文件使用type列,不仅使MySQL能够为您本地跟踪字符编码,而且还使MySQL可以将其转码为备用字符集和/或根据需要检查/操作文本(现在)。或将来)。

SQL数据库需要可打印文本编码(如Base64来处理任意二进制数据)的(错误)想法已被大量不了解情况的教程所延续。这个想法似乎被误认为是错误的信念,因为SQL在其他上下文中仅包含可打印文本,因此它肯定也必须对二进制数据(至少对数据传输(如果不是对数据存储)要求它)。事实并非如此:SQL可以通过多种方式传递二进制数据,包括纯字符串文字(前提是它们像其他字符串一样被正确地引号和转义)。当然,将数据(任何类型)传递到数据库的首选方法是通过参数化查询,参数可以像其他任何东西一样轻松地包含二进制数据。

出于其价值,我通常完全避免在RDBMS中存储这样的项目,而宁愿使用那些高度优化的文件存储数据库(称为 文件系统) ,但这完全是另一回事。

…除非出于性能原因将其缓存…

存储Base64编码的数据可能会带来一些好处的唯一情况是,经常从数据库中检索数据并通过需要该编码的协议进行传输-
在这种情况下,存储Base64编码的表示将不必每次获取时,对其他原始数据执行编码操作。

但是,请注意,从这种意义上讲,Base64编码的存储仅充当 缓存 ,就像出于性能原因可能存储非规范化数据一样。

......在这种情况下,它应该是TEXTBLOB

如上面提到的,之间的差异TEXTBLOB真的可以归结为这样一个事实TEXT列与文本特定的元数据(如存储在一起 的字符编码核对
),而BLOB列不可。这个额外的元数据使MySQL可以在存储和连接字符集之间(适当时)对字符进行代码转换,并执行花式字符等效/排序。

一般而言:如果两个使用不同字符集的客户端应该看到相同的 字节 ,则需要一BLOB列;如果他们应该看到相同的 字符, 则需要一TEXT列。

使用Base64,这两个客户端必须最终发现数据解码为相同的 字节 ;但是他们应该看到编码后的数据具有相同的 字符
。例如,假设一个人希望插入的Base64编码的'Hello world!'(这是'SGVsbG8gd29ybGQh')。如果插入的应用程序正在使用UTF-8字符集,则它将字节序列发送0x53475673624738676432397962475168到数据库。

  • 如果该字节序列存储在BLOB列中,然后由运行在UTF-16 *中的应用程序检索,则将返回 相同的字节这些字节 表示'升噳扇㡧搲㥹扇全'而不是所需的Base64编码值;而

  • 如果该字节序列存储在TEXT列中,然后由运行在UTF-16中的应用程序检索,则MySQL将即时对代码进行转码以返回字节序列0x0053004700560073006200470038006700640032003900790062004700510068,该字节序列表示所需的原始Base64编码值'SGVsbG8gd29ybGQh'

当然,您仍然可以使用BLOB列并以其他方式跟踪字符编码-但这将不必要地重新发明轮子,从而增加了维护复杂性并带来了意外错误的风险。

*实际上,MySQL不支持使用与ASCII字节不兼容的客户端字符集(因此,Base64编码在它们的任何组合中始终保持一致),但是此示例用于说明BLOBTEXT列类型之间的区别,因此解释了为什么TEXT从技术上讲即使在BLOB没有错误的情况下实际上也能正确工作的原因(至少在MySQL添加对非ASCII兼容客户端字符集的支持之前)。



 类似资料:
  • 问题内容: 我正在使用以下代码从我的 Android应用程序中 拍照: 我正在通过POST将此字符串发送到我的PHP服务器,并将其接收到。我有一个数据库,其中有一个type字段。我试图保存在,但它被保存为损坏的图像。我尝试将另存为,但是无论如何也无法正常工作。 我想做三件事: 将图像保存到服务器端数据库(BLOB) 显示图像到网页 将其发送回Android应用。 我在 理解 上述任务所需的不同格式

  • 问题内容: 在数据库中存储图像的常用方法是在存储数据之前将图像转换为数据。此过程将使大小增加33%。或者,可以将图像直接存储为;例如: 然后用 使用后一种方法,我们可以节省1/3的存储空间。为什么像在MySQL数据库中那样存储图像更常见? 更新: 关于将图像存储在数据库中的优点和缺点的争论很多,大多数人认为这不是一种实用的方法。无论如何,在这里我假设我们将图像存储在数据库中,并讨论了这样做的最佳方

  • 问题 你需要使用Base64格式解码或编码二进制数据。 解决方案 base64 模块中有两个函数 b64encode() and b64decode() 可以帮你解决这个问题。例如; >>> # Some byte data >>> s = b'hello' >>> import base64 >>> # Encode as Base64 >>> a = base64.b64encode(s)

  • 我正在数据砖笔记本上运行这个 我得到了这个错误 原因:存储异常:服务器无法对请求进行身份验证。确保授权头的值格式正确,包括签名。 我尝试使用 以获取 Azure Blob 存储中的任何更新,但仍收到上述错误。

  • 我试图将一个Azure Blob存储容器挂载到一个DataBricks实例上,虽然挂载确实有效,但它似乎没有使用存储容器。 我在这里漏掉了什么?

  • 问题内容: 我正在SQLite Manager中创建数据库。我想存储到数据库中。正确显示了另一个字段,但是当我使用数据类型的字段时,它不会显示。 问题答案: 您可以将图像转换为字节数组,并将该字节数组存储在数据库中的blob中。您可以将图像作为字节数组从数据库中检索回来。 如何从imageview获取字节数组: 将字节数组存储在数据库中: 从字节数组中检索图像: