【问题标题】:What column type should be used to store serialized data in a mysql db?应该使用什么列类型将序列化数据存储在 mysql 数据库中?
【发布时间】:2011-07-29 12:30:28
【问题描述】:

应该使用什么列类型将序列化数据存储在 mysql 数据库中? 我知道你可以使用 varbinary、blob、text。什么被认为是最好的,为什么?

编辑: 我知道存储序列化数据并不“好”。不过,我需要在这种情况下这样做。请相信我,如果你有答案,请专注于这个问题。谢谢!

【问题讨论】:

  • 我知道你通常不应该使用它。这是一个真正有意义的特殊情况。

标签: mysql database


【解决方案1】:

除非序列化的数据除了从数据库中保存和恢复之外没有其他用途,否则您可能不希望这样做。

通常,序列化数据有几个字段,这些字段应该作为单独的列存储在数据库中。序列化数据的每一项通常都是单独的列。其中一些列自然是关键字段。除了数据之外,可能还会添加其他列以指示插入发生的日期+时间、负责的用户等。

【讨论】:

  • 嘿沃利。谢谢,这是个特例。我了解您通常不应该序列化数据。如果您能回答序列化数据的最佳列类型,那就太好了。
【解决方案2】:

您打算存储多少?查看string types at the MySQL docs 及其sizes 的规格。这里的关键是你不关心索引这个列,但你也不希望它溢出并被截断,因为那时你的 JSON 是不可读的。

  • TINYTEXT L
  • 文本 L
  • 中文本 L
  • 长文本 L

其中L是字符长度

简单的文本就足够了,但如果你要存储更多,那就更大。不过,在这种情况下,您可能不想将其存储在数据库中。

【讨论】:

  • 我了解长度限制。我更关心博客与文本存储的优缺点。
【解决方案3】:

长文本

Wordpress 将序列化数据作为 LONGTEXT 存储在其 postmeta 表中。我发现 Wordpress 数据库是研究列数据类型的好地方。

【讨论】:

  • Wordpress 应该被用作糟糕的编码、糟糕的做法、糟糕的选择的例子。如果有的话,Wordpress 就是一个如何不设计应用程序的例子
【解决方案4】:

@Twisted Pear 提到的长度限制是很好的理由。

还要考虑TEXT 及其同类具有与之关联的字符集,而BLOB 数据类型则没有。如果您只是存储数据的原始字节,您不妨使用BLOB 而不是TEXT

请注意,您仍然可以将文本数据存储在 BLOB 中,只是不能对其执行任何考虑字符集的 SQL 操作;它只是 SQL 的字节。但这在您的情况下可能不是问题,因为它是序列化数据,其结构对 SQL 来说是未知的。您需要做的就是存储字节并获取字节。字节的解释取决于您的应用程序。

我在使用 LONGBLOBLONGTEXT 使用某些客户端库(例如 PHP)时也遇到了麻烦,因为客户端尝试分配尽可能大的数据类型的缓冲区,但不知道内容会有多大任何给定的行,直到它被提取。这导致 PHP 在尝试分配 4GB 缓冲区时起火。我不知道您使用的是什么客户端,也不知道它是否存在相同的行为。

解决方法:使用MEDIUMBLOB 或只使用BLOB,只要这些类型足以存储您的序列化数据即可。


关于人们告诉你不要这样做的问题,我不会告诉你(尽管我是 SQL 倡导者)。的确,您不能使用 SQL 表达式对序列化数据中的单个元素执行操作,但这不是您的目的。通过将该数据放入数据库,您可以获得的好处包括:

  • 将序列化数据与其他更相关的数据相关联。
  • 能够根据事务范围、COMMIT、ROLLBACK 存储和获取序列化数据。
  • 将所有关系和非关系数据存储在一个位置,以便更轻松地复制到从站、备份和恢复等。

【讨论】:

    【解决方案5】:

    我找到了:

    varchar(5000)
    

    为我们实现尺寸/速度的最佳平衡。此外,它适用于 rails 3 序列化数据(varbinary)间歇性抛出序列化错误。

    【讨论】:

    • 这是最佳答案吗? @djburdick 有什么灵活的方法吗?日期的存储数组(键:1 - 31,值:日期的价格)怎么样?
    • 考虑页面对齐。 4096 或 8192 可能会更好。
    • 我想在这个答案中看到更多的理由。哪种分析表明了这一点?
    【解决方案6】:

    回答:文本在很多 DBMS 中似乎已被弃用,因此最好使用具有上限的 blob 或 varchar(并且使用 blob 您不会遇到任何编码问题,这是 varchar 的主要麻烦和文字)。

    正如this thread at the MySQL forums 中所指出的,硬盘驱动器比软件便宜,因此您最好先设计您的软件并使其工作,然后只有当空间成为问题时,您才可能需要优化这方面。所以不要试图过早地过度优化列的大小,最好一开始就将大小设置得更大(另外这样可以避免安全问题)。

    关于各种 cmets: 这里有太多的 SQL 狂热。尽管我非常喜欢 SQL 和关系模型,但它们也存在缺陷。

    将序列化数据按原样存储到数据库中(例如存储 JSON 或 XML 格式的数据)有几个优点:

    • 您可以使用更灵活的数据格式:动态添加和删除字段、动态更改字段规范等...
    • 与对象模型的阻抗不匹配更少:与获取数据然后必须在程序对象的结构和关系数据库的结构之间进行处理和转换相比,您可以像在程序中一样存储和获取数据.

    还有更多其他优势,所以请不要狂热:关系数据库是一个很棒的工具,但我们不要放弃我们可以获得的其他工具。工具越多越好。

    作为一个具体的使用示例,我倾向于在我的数据库中添加一个 JSON 字段来存储记录的额外参数,其中 JSON 数据的列(属性)永远不会被单独选择,但仅在以下情况下使用已选择正确的记录。 In this case, I can still discriminate my records with the relational columns, and when the right record is selected, I can just use the extra parameters for whatever purpose I want.

    所以我的建议是保留两全其美(速度、可序列化性和结构灵活性),只需使用一些标准关系列作为唯一键来区分您的行,然后使用 blob/varchar 列将插入序列化数据。通常,唯一键只需要两/三列,因此这不会是主要开销。

    此外,您可能对现在具有 JSON 数据类型的 PostgreSQL 以及将 JSON 字段直接处理为关系列的 PostSQL project 感兴趣。

    【讨论】:

    • 某事总有一个用例,因此最好避免使用“不要那样做”之类的答案。我这样说是因为我刚刚阅读了一个帖子,其中有人建议不要将 JSON 数据存储在关系数据库中。但是,正如您所指出的,如果永远不会选择数据并且您希望灵活地存储数据,我认为将 JSON 字符串存储到数据库中没有错。 +1 指出案例...很好的答案!
    【解决方案7】:

    从 MySQL 5.7.8 开始,MySQL 支持原生 JSON 数据类型:MySQL Manual

    【讨论】:

      【解决方案8】:

      我可能迟到了,但是关于序列化对象的 php.net 文档声明如下:

      请注意,这是一个二进制字符串,可能包含空字节,并且 需要这样存储和处理。例如,序列化() 输出通常应存储在数据库的 BLOB 字段中, 而不是 CHAR 或 TEXT 字段。

      来源:http://php.net/manual/en/function.serialize.php

      希望对您有所帮助!

      【讨论】:

        猜你喜欢
        • 2017-12-08
        • 2011-08-18
        • 2017-05-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-29
        • 1970-01-01
        • 1970-01-01
        • 2012-02-27
        相关资源
        最近更新 更多