我在mysql(实际上是mariadb)数据库中存储这样的对象/数据结构:
{
idx: 7,
a: "content A",
b: "content B",
c: ["entry c1", "entry c2", "entry c3"]
}
为了存储它,我使用了两个表,非常类似于这个答案中描述的方法:https://stackoverflow.com/a/17371729/3958875
即
表1:
+-----+---+---+
| idx | a | b |
+-----+---+---+
表2:
+------------+-------+
| owning_obj | entry |
+------------+-------+
然后做了一个视图把它们连接在一起,所以我得到:
+-----+------------+------------+-----------+
| idx | a | b | c |
+-----+------------+------------+-----------+
| 7 | content A1 | content B1 | entry c11 |
| 7 | content A1 | content B1 | entry c21 |
| 7 | content A1 | content B1 | entry c31 |
| 8 | content A2 | content B2 | entry c12 |
| 8 | content A2 | content B2 | entry c22 |
| 8 | content A2 | content B2 | entry c32 |
+-----+------------+------------+-----------+
我的问题是怎样才能把它恢复到我的对象形式(e、 g.我想要一个上面指定的对象类型数组(包含idx在5到20之间的所有条目)
有两种方法我可以想到,但似乎都不是很有效。
首先,我们可以将整个表发送回服务器,它可以制作一个hashmap,其中键是主键或其他一些唯一的索引,然后收集不同的c列,然后用这种方式重建它,但这意味着它必须发送大量重复数据,并且在服务器上重建需要更多的内存和处理时间。如果我们有多个数组,或者数组中有数组,这种方法也不会很容易扩展。
第二种方法是做多个查询,过滤 Table 1
并获取所需的idx列表,然后为每个idx发送一个查询 Table 2
哪里 owning_obj
=当前idx。这意味着要发送更多的查询。
这两种选择似乎都不是很好,所以我想知道是否有更好的方法。目前我在想它可能是 JSON_OBJECT()
,但我不知道怎么做。
这似乎是一个常见的情况,但我似乎找不到确切的措辞来寻找得到答案。
ps:与mysql/mariadb接口的服务器是用rust编写的,但不要认为这与这个问题有关
1条答案
按热度按时间w8rqjzmb1#
你可以用
GROUP_CONCAT
把所有的c
值转换为逗号分隔的字符串。然后在php中分解字符串:
但是,如果条目可能很长,请确保增加
group_concat_max_len
.如果您使用的是mysql 8.0,那么也可以使用
JSON_ARRAYAGG()
. 这将创建entry
值,可以使用json_decode()
. 这样安全一点,因为GROUP_CONCAT()
如果任何一个值包含逗号,都会出错。您可以更改分隔符,但需要一个永远不会出现在任何值中的分隔符。不幸的是,这不是在马里亚德。