我应该在 MySQL 中为 JSON 使用 blob 还是 text?

Posted

技术标签:

【中文标题】我应该在 MySQL 中为 JSON 使用 blob 还是 text?【英文标题】:Should I use blob or text for JSON in MySQL? 【发布时间】:2012-04-29 10:13:09 【问题描述】:

我打算在我的数据库中存储一个json_encoded 字符串。我不能准确地说出它的长度,但我很确定它会很长。我关心的是我将为此使用哪种字段类型,是blob 还是text

我更喜欢可以尽可能节省空间而不是快速搜索的那一种,无论如何我还有其他列我应该只索引。

【问题讨论】:

【参考方案1】:

mysql 的文档中所述,从 5.7.8 开始支持原生 JSON 数据类型。

与将 JSON 格式的字符串存储在字符串列中相比,JSON 数据类型具有以下优势:

自动验证存储在 JSON 列中的 JSON 文档。无效文档会产生错误。 优化的存储格式。存储在 JSON 列中的 JSON 文档被转换为允许对文档元素进行快速读取访问的内部格式。当服务器稍后必须读取以这种二进制格式存储的 JSON 值时,不需要从文本表示中解析该值。二进制格式的结构使服务器能够直接通过键或数组索引查找子对象或嵌套值,而无需读取文档中它们之前或之后的所有值。

因此,正如 MySQL 文档所述,应使用 JSON 数据类型而不是文本。

【讨论】:

优化的存储格式。这是否意味着需要更小的空间? 从此链接检索:dev.mysql.com/doc/refman/5.7/en/json.htmlThe space required to store a JSON document is roughly the same as for LONGBLOB or LONGTEXT; 根据我的经验,使用 JSON 数据类型会弄乱存储键的顺序。例如,在编码之前,我的数据是:['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]。在将此数据编码并存储为 JSON 数据类型后,我发现数据存储为"c": "3", "a": "1", "b": "2", "d": "4"。我尝试使用JSON_FORCE_OBJECT 作为json_encode 的选项,但这并没有帮助。您知道我们如何保留 JSON 数据类型中的数组元素/键的顺序吗? @Devner 您所描述的内容(字典、关联数组或哈希图)本质上是无序的。您需要存储一个映射以保持其中一个有序。 @Devner 为您的对象添加一个有序数组,我们称之为keysOrder。它将按照您想要的顺序包含您的密钥。当您解析/解码您的 json 时,您需要根据 keysOrder 数组重新排序键。例如:"c": "3", "a": "1", "b": "2", "d": "4", "keysOrder": ['a', 'b', 'c', 'd']【参考方案2】:

blob 通常用于图像、二进制文件等。text 应该足够适合您的情况,或者如果您真的担心的话,您可以使用空间容量更大的longtext

搜索方面,由于您存储json_encode'd 的东西,您仍然需要调用json_decode 以使其在您的应用程序中有用,我认为数据类型的选择并不重要这种情况。

更好的方法是规范化你的数据库设计,而不是将相关的东西存储在一大串 json 中。

【讨论】:

感谢您的真知灼见。 我大约 2 年零 11 个月后,但对于 webhook 的有效负载,在等待发送的同时存储序列化的 JSON 似乎是一个很好的用例。如果有人有不同的想法,我很乐意提供反馈。 Pinterest 也在 text 中存储 JSON,他们在 recently published it in this article (scroll down half way)。 我认为 mysql 中的 text 比 longtext 大。 json 数据类型默认为 longtext,这对日常的 json 对象没有好处。

以上是关于我应该在 MySQL 中为 JSON 使用 blob 还是 text?的主要内容,如果未能解决你的问题,请参考以下文章

java - 如何在java中为mysql的JSON数据类型使用准备好的语句?

尝试在 MYSQL 中为当前月份创建 6 个月滚动

如何在 MySQL 中为行保留一个计数器

我们应该在转换通用 json 响应时使用“any”吗

如何在 Uniface 中为 json 结构创建一个列表

如何在 MySQL 中的 json 列上创建索引?