应该使用什么列types来将序列化数据存储在mysql数据库中?

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

编辑:我知道这不是“好”来存储序列化的数据。 我需要在这个案例中做到这一点。 请相信我,关注这个问题,如果你有答案。 谢谢!

要回答:在许多DBMS似乎不推荐使用文本,所以最好使用一个blob或一个具有高限制的varchar(和blob你将不会得到任何编码问题,这是一个与varchar和文本的麻烦) 。

也正如MySQL论坛上的这个话题所指出的那样,硬盘比软件便宜,所以你最好先devise你的软件并使其工作,只有当空间成为问题时,你才可能想要优化这个方面。 所以,不要试图过早地优化列的大小,最好先将大小设置得更大(这样可以避免安全问题)。

关于各种意见:这里太多的SQL狂热。 尽pipe我非常喜欢SQL和关系模型,但他们也有自己的缺陷。

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

  • 你可以有一个更灵活的数据格式:dynamic添加和删除字段,更改dynamic领域的规格等…
  • 与对象模型的阻抗不匹配程度较低:与存储在数据中相比,存储和获取数据与获取数据相比,然后必须在程序对象的结构和关系数据库结构之间进行处理和转换。

还有更多的其他优点,所以请不要迷恋:关系数据库是一个很好的工具,但是我们不要去讨论我们可以得到的其他工具。 更多的工具,更好。

至于具体的使用例子,我倾向于在我的数据库中添加一个JSON字段来存储logging的额外参数,其中JSON数据的列(属性)将永远不会被单独select,而只会在正确的logging已被选中。 在这种情况下,我仍然可以用关系列区分我的​​logging,当select正确的logging时,我可以使用额外的参数来达到我想要的目的。

所以我的build议是保留世界上最好的(速度,可序列化和结构的灵活性),只是使用一些标准的关系列作为区分你的行的唯一键,然后使用一个blob / varchar列,你的序列化数据将被插入。 通常,唯一的密钥只需要2/3列,因此这不是一个主要的开销。

另外,PostgreSQL现在有一个JSON数据types,而PostSQL项目可以像关系列一样直接处理JSON字段。

你打算存多less钱? 查看MySQL文档中stringtypes的规格及其大小 。 这里的关键是,你不关心索引这个列,但你也不希望它溢出和截断,因为那么你的JSON是不可读的。

  • TINYTEXT L <2 ^ 8
  • TEXT L <2 ^ 16
  • MEDIUMTEXT L <2 ^ 24
  • LONGTEXT L <2 ^ 32

L是字符的长度

只要简单的文字应该是足够的,但如果你储存更多的话,就更大了。 但是,在这种情况下,你可能不想把它存储在数据库中。

LONGTEXT

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

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

还要考虑到TEXT及其同类有一个与它们相关的字符集 ,而BLOB数据types则没有。 如果你只是存储原始字节的数据,你可以使用BLOB而不是TEXT

请注意,您仍然可以将文本数据存储在BLOB ,但是您不能对其进行任何SQL考虑; 这只是SQL的字节。 但是,这可能不是一个问题,因为它是序列化的数据结构无论如何SQL不知道。 所有你需要做的是存储字节和提取字节。 字节的解释取决于您的应用程序。

我也遇到过使用某些客户端库(例如PHP)使用LONGBLOBLONGTEXT麻烦,因为客户端试图分配一个尽可能大的数据types的缓冲区,不知道在获取任何给定的行之前内容会有多大。 这导致PHP试图分配一个4GB缓冲区时爆发出火焰。 我不知道你使用的是什么客户端,或者是否有同样的行为。

解决方法:使用MEDIUMBLOBBLOB ,只要这些types足以存储序列化的数据。


在人们告诉你不要这样做的问题上,我不会告诉你(尽pipe我是SQL的拥护者)。 确实,您不能使用SQLexpression式对序列化数据中的单个元素执行操作,但这不是您的目的。 将这些数据放入数据库可以获得什么结果,包括:

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

从MySQL 5.7.8开始,MySQL支持本机JSON数据types: MySQL手册

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

通常情况下,序列化的数据有几个字段应该作为单独的列存储在数据库中。 序列化数据的每一项都是一个单独的列。 其中一些栏目自然是关键领域。 除了数据之外,还可以添加其他列以指示插入发生的date和时间,责任用户等等。

我发现:

 varchar(5000) 

为我们的尺寸/速度的最佳平衡。 此外,它与轨道3序列化数据(varbinary)间歇性抛出序列化错误。