教义数组 vs simple_array vs json_array

Posted

技术标签:

【中文标题】教义数组 vs simple_array vs json_array【英文标题】:Doctrine array vs simple_array vs json_array 【发布时间】:2013-05-11 08:47:10 【问题描述】:

我正在使用 symfony 和教义作为我的 ORM。

对于我有的可用类型:

数组 simple_array json_array

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

我可以为他们每个人做一个演示来说明差异吗?

我已经在某些应用程序中使用了 simple_array,但我发现我不理解 formType...(或者我没有很好地使用它!?)

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

我有一个必须在特定日期运行的任务 所以我用 days 属性创建了 TaskEntity

天数是:

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

但我不知道选择上述哪种类型...

【问题讨论】:

如果您使用json_array,请记住事实上(由于错误doctrine-project.org/jira/browse/DBAL-446)它永远不可能是null,即使它被声明为nullable=true(当实体是由学说构建/水合)。所以为了避免这个问题,always 为你的$myJsonArray 属性设置值array()。这样您的属性定义将是:/* @Column(type="json_array) */ private $myJsonArray = array();。并检查它是否通过empty($this->myJsonArray) 设置但不是null === $this->myJsonArray() 另一个未修复的相同错误的链接:github.com/doctrine/dbal/issues/1643 【参考方案1】:

对于你的问题simple_array是正确的方式,正确的方式也可能会创建七个布尔字段。

但是这里有一点vademecum:

从原则上了解类型如何工作的最好方法是阅读类型的代码,这是因为有几个细节被认为是理所当然的,或者文档中没有真正解释。

所以你可以进入

/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 月更新

现在有一个完整且更新的文档here json_array 已弃用,取而代之的是 json 类型,它将利用 json 字段的新数据库功能

【讨论】:

OP cmets 中提到:json_array 在值为null 时返回一个空数组。这是一个错误:github.com/doctrine/dbal/issues/1643 json_array 已弃用 doctrine-project.org/projects/doctrine-dbal/en/2.7/reference/…【参考方案2】:

如上所述,解决问题的最佳方法是使用 arrayjson_array 类型的数组映射,但不是 simple_array。原因是simple_array 的序列化方法只是对implode(',', $array) 的调用,它只会保留数组的值而不是键,因此对于您有关联数组的情况无效。

但是,您也可以将 $days 属性建模为基于 0 的数组(即,星期一为零,星期二为 1,等等)。在这种情况下,它会起作用,因为使用 explode(',', $serialized); 进行反序列化会生成一个带有序列化值的基于 0 的数组。

【讨论】:

【参考方案3】:

根据文档:

Doctrine ORM > Basic Mapping > Doctrine Mapping Types

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

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

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

    重要提示:仅当您确定您的值不能包含 , 时才使用此类型。

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

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

【讨论】:

【参考方案4】:

另一个考虑因素:表示一小组真/假值的最有效方法是bitfield。

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

请参阅https://***.com/a/5412214/827254 了解一个很好的例子。

【讨论】:

以上是关于教义数组 vs simple_array vs json_array的主要内容,如果未能解决你的问题,请参考以下文章

文心一言 VS 讯飞星火 VS chatgpt (18)-- 算法导论4.1 5题

在 Doctrine 中用于 simple_array 字段的数组到字符串转换

20210828每日总结

冒泡排序VS选择排序

log4j vs slf4j vs logback vs commons-logging

HDU3076 ssworld VS DDD