Doctrine数组 vs 简单数组 vs JSON数组

73

我正在使用Symfony和Doctrine作为我的ORM。

可用的类型有:

  • array
  • simple_array
  • json_array

我想知道它们之间的区别是什么:我该何时使用其中之一?

可以为每个类型给出演示以说明差异吗?

我已经在一些应用程序中使用了simple_array,但我发现我不理解formType…(或者可能我没有使用好!?)

为了说明我的问题,这里有一个例子:

我有一个任务,必须在特定的日期运行,因此我创建了一个TaskEntity,其中包含days属性。

天数将会是:

$days = array(
    1=>true,
    2=>true,
    3=>true,
    4=>true,
    5=>true,
    6=>false,
    7=>false
);

但是我不知道要选择上面的哪种类型...


3
如果您使用 json_array,请记住,实际上(因为bug http://www.doctrine-project.org/jira/browse/DBAL-446),即使声明为`nullable=true`(当由Doctrine构建/填充实体时),它也永远不可能是 null。 所以为了解决这个问题,_始终_为您的 $myJsonArray 属性设置值 array()。 因此,您的属性定义应该是:/* @Column(type="json_array) */ private $myJsonArray = array();。 并通过 empty($this->myJsonArray) 而不是 null === $this->myJsonArray() 来检查它是否设置。 - Dimitry K
1
同一个仍未解决的错误的另一个链接:https://github.com/doctrine/dbal/issues/1643 - ar34z
5个回答

140

针对您的问题,simple_array 是正确的方法,这种方法也可能会创建七个布尔字段。

然而,这里有一本小指南:

了解一个 doctrine 类型的最好方法是阅读类型的代码,这是因为有许多细节被视为理所当然或在文档中没有真正解释清楚。

因此,您可以转到

/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php

找到你的类型并检查它的方法是否符合你的要求。

以下是一些细节:

simple_array

/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php 中。

return implode(',', $value);

这只是一些项目的 implode()/explode(),仅存储值,并且非常有用,因为您可以轻松地查询数据库。

数组

/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php 中。

return serialize($value);

调用PHP的serialize()/unserialize()函数,比json_array更快。从代码来看,我认为它也适用于对象。显然,如果将字段视为纯文本,则无法理解。

json_array

/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php中。

return json_encode($value);

它调用json_encode()/json_decode(),如果你查看字段,你可以看到一个未格式化的JSON数组,但它比PHP的序列化对象更易读,并且更便携(JSON存在于各处)。

2018年6月更新

  • 现在有一个完整而更新的文档在这里
  • json_array已被弃用,取而代之的是json类型,它将利用新的数据库功能来处理json字段

1
如OP评论中所述:“当值为null时,json_array返回一个空数组。” 这是一个错误:https://github.com/doctrine/dbal/issues/1643 - ar34z
4
json_array已被弃用。请参考https://www.doctrine-project.org/projects/doctrine-dbal/en/2.7/reference/types.html。 - hayzem

12

另一个需要考虑的问题是:表示像这里呈现的一小组真/假值最有效的方式将是使用位域

这样,你只需要存储一个整数而不是完整的字符串。并且避免了编码/解码开销。

请参见https://dev59.com/02435IYBdhLWcg3wfgMf#5412214,其中包含一个很好的例子。


3
根据所述,解决您问题的最佳方法是使用类型为arrayjson_array的数组映射,而不是simple_array。原因是simple_array的序列化方法只是调用implode(',', $array),这将仅保留数组的值而不是键,因此对于您具有关联数组的情况无效。
但是,您还可以将$days属性建模为基于0的数组(即星期一为零,星期二为1等)。在这种情况下,它将起作用,因为使用explode(',', $serialized);进行反序列化会生成一个基于0的数组,其中包含序列化的值。

2
根据文档:

Doctrine ORM > 基本映射 > Doctrine映射类型

关于数组数据,您有三种选择:

  1. array 类型,使用 serialize()unserialize() 将 SQL CLOB 映射到 PHP 数组。

  2. simple_array 类型,使用 implode()explode()以逗号为分隔符,将 SQL CLOB 映射到 PHP 数组。

    重要提示:仅在您确定值中不包含 ,(逗号)时使用此类型。

  3. json_array 类型,使用 json_encode()json_decode() 将 SQL CLOB 映射到 PHP 数组。

因此,如果您确定数组值中没有 ,(逗号),请使用 simple_array。如果您有一个简单的数组结构(线性结构),请使用 array;如果您有更复杂的键值数组,请使用 json_array


0

来自www.doctrine-project.org reference

数组类型

将数组数据映射到不同的变体中,例如简单数组、真实数组或JSON格式数组。

array

基于PHP序列化映射和转换数组数据。如果您需要存储数组数据的精确表示,应考虑使用此类型,因为它使用序列化将您的数组的精确副本表示为字符串存储在数据库中。从数据库检索的值始终使用反序列化转换为PHP的数组类型,如果没有数据,则返回null。

simple_array

基于PHP逗号分隔的串联和分裂映射和转换数组数据。如果您知道要存储的数据始终是基于标量值的一维数组,则应考虑使用此类型,因为它使用简单的PHP串联和分裂技术对数据进行序列化和反序列化。从数据库检索的值始终使用逗号分隔的explode()转换为PHP的数组类型,如果没有数据,则返回null。

json

基于PHP的JSON编码功能,映射和转换数组数据。如果您知道要存储的数据总是以有效的UTF-8编码的JSON格式字符串形式存在,那么应该考虑使用此类型。从数据库检索到的值始终使用PHP的json_decode()函数转换为PHP的本机类型。JSON对象始终转换为PHP关联数组。


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