数据库中的JSON与序列化数组比较

75
在将JSON数据存储到MySQL数据库中与序列化数组之间有哪些优缺点?

这个问题应该重新开放。虽然存在一些“基于观点”的风险,但问题并没有要求观点,它明确要求优缺点。而且顶级答案也不是基于观点的,它们清楚地用证据支持事实。 - AutoBaker
11个回答

100
  1. JSON 编码() & 解码()
    • PHP 版本 >= 5.0.0
      • 嵌套层数的限制为20。
    • PHP 版本 >= 5.2.3
      • 嵌套层数的限制为128。
    • PHP 版本 >= 5.3.0
      • 嵌套层数的限制为512。
    • 相对于 PHP 的序列化字符串,占用空间更小。
  2. 序列化() & 反序列化()
    • PHP 版本 >= 4.0.0
      • 在 PHP 数据类型对象上不会丢失方法。
      • 任何被反序列化的对象都会调用 __wakeup() 魔术方法。(非常强大)
      • 已经注意到,将字符串使用base64编码后存入数据库,然后用此函数取出字符串时进行base64解码,有时可以更好地处理某些空格字符的问题。

选择权在你手中。


18
点赞了 __wakeup() 函数。 - altermativ
我正在存储Twitter返回的JSON,所以我需要使用base64_encode来避免转义奇怪的字符。 - Eric Cope
关于serialize的一个非常重要的事情是,它保留了正确序列化对象类型的信息。https://wordpress.stackexchange.com/a/61094/91844 - Arnis Juraga

89

专业JSON:

  • JSON数据可以被许多不同的语言使用,不仅限于PHP
  • JSON数据易读易写。
  • 它占用更少的空间
  • 编码JSON比序列化更快

专业序列化数组:

  • 反序列化比JSON解码更快

正如评论所指出的那样,JSON占用的空间比序列化数组少。我还检查了JSON或序列化哪个更快,令人惊讶的是,JSON编码比序列化更快。不过,反序列化比JSON解码更快。

这是我用来测试的脚本:

<?php 
function runTime(){
      $mtime = microtime(); 
      $mtime = explode(' ', $mtime); 
      $mtime = $mtime[1] + $mtime[0]; 
      return $mtime; 
}
?> 
<pre>
<?php
$start = runTime();

$ser;

for($i=0; $i<1000; $i++){
    $a = array(a => 1, x => 10);
    $ser = serialize($a);
}
$total = runTime() - $start;
echo "Serializing 1000 times took \t$total seconds";
?>

<?php
$start = runTime();

$json;

for($i=0; $i<1000; $i++){
    $a = array(a => 1, x => 10);
    $json = json_encode($a);
}
$total = runTime() - $start;
echo "JSON encoding 1000 times took \t$total seconds";
?>

<?php
$start = runTime();

$ser;

for($i=0; $i<1000; $i++){
    $a = unserialize($ser);
}
$total = runTime() - $start;
echo "Unserializing 1000 times took \t$total seconds";
?>

<?php
$start = runTime();

$json;

for($i=0; $i<1000; $i++){
    $a = json_decode($json);
}
$total = runTime() - $start;
echo "JSON decoding 1000 times took \t$total seconds";
?>
</pre>

JSON:{"x":1,"b":"e"}序列化:a:2:{s:1:"x";i:1;s:1:"b";s:1:"e";}因此,JSON占用的空间更小... - Thinker
谢谢Thinker,我以为PHP序列化器会将其序列化为某种字节码,而不是字符串。现在我感到相当失望。 - Marius
3
PHP序列化格式包括元素(字符串和数组)的长度,因此它比JSON写入速度慢(JSON不存储长度),但读取速度更快(当您读取文件时知道预期内容时,需要实现的条件逻辑较少。例如,要导入一个2000个字符的字符串,只需读取下一个2000个字符,而无需每次检查当前字符是否表示字符串的结束符,就像对json_decode所做的那样)。 - E Ciotti
注意:MySQL 5.7.8+ 包括对 JSON 的本地支持。 - dreftymac

31

可移植性:JSON 获胜。 JSON 支持更多平台,而 PHP 反序列化只被 PHP 支持(据我所知)。虽然任何语言都可以解析这两种格式,但是 JSON 有更多预构建的库。

未来性:JSON 获胜。JSON 是一种“标准”,就像 JavaScript 是一种标准一样,并且不太可能在未来发生变化。PHP 组没有对序列化格式的未来做出承诺,虽然未来不太可能发生变化,但一个组控制该格式意味着您可能会遇到未来无法读取的数据。

保真度:PHP 获胜。 PHP 序列化允许您使用本机 PHP 数据类型存储数据,包括自定义类定义的对象。 JSON 仅允许您存储通用基元类型、通用列表(“数组”)和键/值对对象。如果您正在开发 PHP 应用程序,则 PHP 序列化在此方面可能提供一些优势。

文件大小:JSON 在这里稍微获胜,因为 PHP 的当前序列化格式比较冗长(因为它存储了更多信息)。

性能:谁知道,这取决于具体情况,请进行性能分析。

结论:除非您有强烈的理由使用 PHP 序列化,否则请使用 JSON。


7

JSON更具可移植性,即可以更轻松地从不同的语言中读取/写入它等。如果您使用PHP序列化数组,则只能轻松地使用PHP来访问它。


不同意,当作为微服务使用时,这将不是一个问题。 - Yoosuf Mo
@Yoosuf,你不同意什么?我从来没有说这是个问题。 - Tom Haigh

7
你是否只使用PHP来处理数据?如果是:使用数组,如果不是:使用JSON。
数组的优势:
- 会话使用序列化:认为它比json_encode / decode更快(不太确定)。 - PHP中有许多关于数组的函数(如排序/合并等)。
JSON的优势:
- JSON在其他语言和Web语言中都广泛应用。 - 数据库中不冗长。 - 许多工具,例如XML:JSON Schema。

4

JSON可以区分对象和数组,{"member1":"value", "member2":["member1", "member2"]}。 - LM.
3
LithMaster,你应该学习一下什么是关联数组。它不像你例子中的那种数组。 - Thinker

3

对于数组和与Javascript或其他语言的通信,请使用json。对于对象或任何内部PHP工作,用serialize处理当前运行的脚本。


2

如果您想在JSON.stringify(obj)中避免引号和特殊字符,可以使用PHP的数据库特定转义方法。

<?php
mysql_real_escape_string(htmlspecialchars($value))
?>

你现在可以安全地存储它,并在读取时进行解码。

2
我刚遇到了一个关于php序列化的大问题。我在单个字段中存储了大量数据,然后使用unserialize进行读取。
结果是,该字段中出现了一些损坏的数据。serialize将数据映射为代码,例如'a'、's'和'N'。如果有损坏的数据,映射就会失败。这将显示一个php错误,因为unserialize函数无法工作,由于字节码错误。
所以我的观点是要避免使用serialize。使用JSON更安全,你不会在未来遇到主要问题而感到头疼。
对我来说,不再使用serialize。

2

正如大多数答案所指出的那样,JSON比序列化更胜一筹。我认为最大的优点是它的平台无关性。您可能有其他应用程序与您的数据库通信,它们可能与PHP毫不相干。

但是两种解决方案都违反了数据库规范化。您的数据库甚至不在第一范式中,因此您无法利用任何数据库功能,例如搜索。更好的方法是使用对象关系映射。有很好的库可用 - 例如考虑使用Doctrine ORM


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接