当前位置: 首页 > 知识库问答 >
问题:

使用JSONB列中的值连接表

白烨煜
2023-03-14

有两个表格:

授权联系人(auth_Contacts):

(
userid varchar
contacts jsonb
)

联系人包含具有属性的联系人数组{contact_id,type}

讨论

(
contact_id varchar
discussion_id varchar
discussion_details jsonb
)

auth_contacts至少有100k条记录,使其成为非JSONB类型是不合适的,因为它会使记录量增加一倍或三倍。

auth_联系人的样本数据

userid  | contacts
'11111' | '{"contact": [{"type": "type_a", "contact_id": "1-A-12"}
                      , {"type": "type_b", "contact_id": "1-A-13"}]}'

讨论表有500万奇数记录。

我想参加讨论。contact_id(关系列),带有contact id,在auth_contacts中的json对象数组中包含一个json对象。联系人

一个非常粗糙的方法是:

SELECT *
FROM discussion d 
JOIN (SELECT userid, JSONB_OBJECT_KEYS(a.contacts) AS auth_contact
      FROM auth_contacts a) AS contacts
      ON (d.contact_id = contacts.auth_contact::text)

这实际上是在运行时创建(内部sql)userid vs contact id table(这是我一直在避免的,因此选择了JSONB数据类型)。对于一个有大量记录的用户,这个查询需要26秒,这并不都是好的。尝试了其他几种方法:PostgreSQL 9.4:数组内JSON字段id上的聚合/联接表

但是应该有一个更干净,更好的方法,这将是简单的JOINd.contact_id=联系人-

搜索网络时,这似乎是一项相当繁琐的任务?


共有1个答案

岳和泽
2023-03-14

你的“粗暴的方式”实际上行不通。这是另一种粗暴的方式:

SELECT *
FROM  auth_contacts a
    , jsonb_to_recordset(a.contacts->'contact') AS c(contact_id text)
JOIN  discussion d USING (contact_id);

如前所述,还可以使用contains操作符@

SELECT *
FROM   auth_contacts a
JOIN   discussion d ON a.contacts->'contact'
                    @> json_build_array(json_build_object('contact_id', d.contact_id))::jsonb

而是使用JSON创建函数,而不是字符串连接。看起来很麻烦,但如果支持功能性jsonb_path_ops-GIN索引,实际上会非常快:

CREATE INDEX auth_contacts_contacts_gin_idx ON auth_contacts
USING  gin ((contacts->'contact') jsonb_path_ops);

细节:

  • 用于在JSON数组中查找元素的索引

这一切都很有趣,但这里的问题是关系模型。您的索赔:

因此,将其设为非JSONB类型是不合适的,因为它会使记录量增加一倍或三倍。

与正确的相反。将连接表所需的ID包装为JSON文档类型是无稽之谈。使用多对多关系规范化您的表,并将您在数据库中使用的所有ID实现为具有适当数据类型的单独列。基础知识:

  • 如何在Postgres 9.4中对JSONB类型的列执行更新操作

 类似资料:
  • 在我的Java项目中,我是usinq、JOOQ,我希望更新JSONB值。但我的建造失败了。 我写了一段代码: 我收到了下一条信息: 我犯错的地方?

  • 问题内容: 可以说我在PostgreSQL中有一个带有以下各列的表: 我插入了这两行: 我想将上面的行转换为此(在PostgreSQL中进行选择): 调用PHP 并得到这样的东西: 但是现在,如果我用php调用,我会得到: 希望有人能帮助我解决这个问题,谢谢大家 问题答案: 在9.4中很简单(使用了LATERAL join和jsonb函数): 确切结果:

  • 问题内容: 使用运算符将产生以下结果: 我希望能够实现以下结果(对于操作员来说只是一个占位符): 因此,您可以看到顶级键的子值已“合并”,使得结果包含和。 如何在Postgres中“深度”合并两个 JSONB 值? 如果可能的话,这可能吗? 一个更复杂的测试用例: 原始“合并”并成为对象的另一个测试用例: 问题答案: 您应该合并两个值都使用的未嵌套元素。在不平凡的查询中执行此操作可能会感到不舒服,

  • 问题内容: 我有一张桌子叫: 每个都与一个不同的表相关,field的值指定了我要用于该表的表的名称。所有目标表都有几个相似的列: 当前,我正在使用此查询来选择通知,通知它们在目标表中存在相关行,并且其字段为: 但是由于它是a ,如果它与任何表都不匹配,它将返回通知,我该如何重写它,以便它不返回与目标表中的任何行都不匹配的通知?我也尝试了不成功的声明。 问题答案: 我不是100%肯定语法正确,并且现

  • 假设我有两个数据帧df1:col1 col2 col3 df2:col1 col2 col4 我想使用col1和col2连接两个数据帧,而不定义新的别名表名。 我不想做 df=df1.join(df2,(df1.col1==df2.col1) 所以最终的数据帧只有col1 col2 col3 col4 如何实现这一点?

  • 我有大约10000个短视频,我正在尝试制作一些更长的视频。 我使用MoviePy创建了这些视频,但在尝试将它们重新连接在一起时,会不断出现内存错误。 在我的代码中,我有一个外部循环遍历字母表的每个字母并获取以该字母开头的文件。 从返回的视频拆条中,我得到视频最后3.5秒()的长度和拆条,然后将其添加到Python列表中。 我陷入困境的地方是,我想把这个剪辑过的视频列表拿出来,然后从中制作一个很长很