sql - 使用 JSONB 列中的值连接表

标签 sql postgresql-9.4 jsonb

有两个表:

授权联系人 ( auth_contacts ):

(
userid varchar
contacts jsonb
)
contacts包含一组具有属性的联系人 {contact_id, type}discussion :
(
contact_id varchar
discussion_id varchar
discussion_details jsonb
)

auth_contacts至少有 10 万条记录,因此非 JSONB 类型是不合适的,因为它会使记录数量增加一倍或三倍。
auth_contacts 的样本数据:
userid  | contacts
'11111' | '{"contact": [{"type": "type_a", "contact_id": "1-A-12"}
                      , {"type": "type_b", "contact_id": "1-A-13"}]}'
discussion表有 500 万条奇数记录。

我想加入 discussion.contact_id (关系列)具有联系人 ID,其中一个 json 对象位于 auth_contacts.contacts 中的 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)用户 ID 与联系人 ID 表(这是我避免的,因此使用 JSONB 数据类型
对于具有大量记录的用户,此查询需要 26 秒以上的时间,这并不是很好。
尝试了其他几种方式:PostgreSQL 9.4: Aggregate / Join table on JSON field id inside array

但是应该有一种更清洁更好的方法,就像
加入 d.contact_id = contacts -> contact -> contact_id?当我尝试这个时,它不会产生任何结果。

在网上搜索时,这似乎是一项非常繁琐的任务?

最佳答案

概念证明
您的“粗暴方式”实际上不起作用。这是另一种粗略的方法:

SELECT *
FROM  auth_contacts a
    , jsonb_to_recordset(a.contacts->'contact') AS c(contact_id text)
JOIN  discussion d USING (contact_id);
正如已经评论过的,您还可以使用 contains operator @> 来制定连接条件。 :
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);
细节:
  • Index for finding an element in a JSON array
  • Postgres 9.4 jsonb array as table

  • 正确的解决方案
    这一切都很有趣,但这里的问题是关系模型。您的主张:

    hence making it non JSONB type is not appropriate according as it would double or triple the amount of records.


    与正确的相反 .它是 废话 将表连接到 JSON 文档类型所需的 ID 包装起来。使用多对多关系规范化您的表,并将您在数据库中使用的所有 ID 实现为具有适当数据类型的单独列。基本:
  • How to perform update operations on columns of type JSONB in Postgres 9.4
  • How to implement a many-to-many relationship in PostgreSQL?
  • 关于sql - 使用 JSONB 列中的值连接表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31309362/

    相关文章:

    mysql - SQL SELECT 语句 MAX 日期和表连接

    java - 为数据库增加值(value)

    postgresql - 如何将 varchar 转换为 bool 值

    postgresql - Postgres jsonb_set 连接当前值

    django - JSONB PostgreSQL 类型 : how to lookup

    mysql - SQL:连接具有大量列的表时删除重复列

    sql - 如何检查值的最后 4 位数字是否在 SQL Server 中的范围内

    sql - 选择多对中的位置 - postgresql

    Postgresql 不使用多列索引 (btree_gin)

    sql - Postgres JSONB : query by negative numbers