使用 JSONB 列内的值连接表

2023-11-22

有两个表:

授权联系人(auth_contacts):

(
userid varchar
contacts jsonb
)

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

discussion:

(
contact_id varchar
discussion_id varchar
discussion_details jsonb
)

桌子auth_contacts至少有 100k 条记录,使其成为非 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 对象数组内有一个 json 对象auth_contacts.contacts.

一种非常粗暴的方法是:

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:数组内 JSON 字段 id 的聚合/连接表

但应该有一种更干净、更好的方法,就像这样简单 加入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);

正如已经评论过的,您还可以使用以下方式制定连接条件包含运算符@>:

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 index:

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

Details:

  • 用于在 JSON 数组中查找元素的索引
  • Postgres 9.4 jsonb 数组作为表

正确的解决方案

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

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

is 与正确的相反. It's nonsense将连接表所需的 ID 包装成 JSON 文档类型。使用多对多关系规范化您的表,并将您在数据库中使用的所有 ID 实现为具有适当数据类型的单独列。基本:

  • 如何对 JSONB 类型的列执行更新操作
  • 如何在PostgreSQL中实现多对多关系?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 JSONB 列内的值连接表 的相关文章

  • 限制分页页数

    objConnect mysql connect localhost root or die mysql error objDB mysql select db Test strSQL SELECT FROM UserAddedRecord
  • 一张表中按最大日期过滤重复行的 SQL 查询

    我有一个 SQL 数据库 persons 它具有基于 IDNum 列的重复条目 我需要查询条目并仅根据最新创建日期显示行或重复条目 这是查询 SELECT IDNum PersonPGUID CreatedDateTime FirstNam
  • 使用来自另一个的 SELECT 更新表,但字段为 SUM(someField)

    基本上我有这样的事情 UPDATE Table SET Table col1 other table col1 FROM Table INNER JOIN other table ON Table id other table id 问题是
  • PostgreSQL 和锁定

    希望一些比我更聪明的 DBA 可以帮助我找到一个好的解决方案来完成我需要做的事情 为了便于讨论 我们假设我有一个名为 work 的表 其中包含一些列 其中一列表示给定客户端对该行工作的所有权 场景是 我将连接 2 个客户端并轮询表以查找要完
  • SQL中如何识别字符串的第一个字符是数字还是字符

    我需要将数据中的第一个字符识别为 SQL Server 中的数字或字符 我对此比较陌生 我不知道从哪里开始 但这是我到目前为止所做的事情 我的数据看起来像这样 TypeDep Transfer From 4Z2 Transfer From
  • 我的用例可以合并到单个查询中而不影响性能吗?

    我主要着眼于改善表现查询的内容以及是否能够解决单一查询对于我的用例之一 解释如下 涉及到2张表 Table 1 EMPLOYEE column1 column2 email1 email2 column5 column6 Table 2 E
  • 合并并添加两个表中的值

    是否可以制作一个在两个表中添加值的查询 例如 假设您有两张表 id value a 1 c 2 d 3 f 4 g 5 and id value a 1 b 2 c 3 d 4 e 5 然后 当您 添加 两个表时 您将获得 id 匹配的结果
  • 如何在审计触发器中使用system_user但仍使用连接池?

    我想做以下两件事 在我的数据库表上使用审计触发器来识别哪个用户更新了什么 使用连接池来提高性能 对于 1 我在数据库触发器中使用 system user 来识别进行更改的用户 但这阻止我执行需要通用连接字符串的 2 有没有一种方法可以让我充
  • 如何创建包含多列MD5的GENERATED列?

    我尝试在 PostgreSQL 14 3 中添加下表 CREATE TABLE client cache id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY request VARCHAR
  • 什么是动态 SQL 查询?何时需要使用动态 SQL 查询?

    什么是动态 SQL 查询 何时需要使用动态 SQL 查询 我正在使用 SQL Server 2005 这里有几篇文章 动态SQL简介 http www sqlteam com article introduction to dynamic
  • PL/SQL 过程:如何返回 select 语句?

    我想创建一个存储过程 on ORACLE数据库服务器我的问题是 我不知道如何返回 select 语句 这是程序中应包含的逻辑 输入参数 过滤器1 int 过滤器2 字符串 with cte as select val1 val2 stdde
  • 如何在postgresql中编写有关最大行数的约束?

    我认为这是一个很常见的问题 我有一张桌子user id INT 和一张桌子photo id BIGINT owner INT 所有者是一个参考user id 我想向表照片添加一个约束 以防止每个用户将超过 10 张照片输入数据库 写这个的最
  • 如何获得组中“中间”值的平均值?

    我有一个包含值和组 ID 的表 简化示例 我需要获取中间 3 个值的每组的平均值 因此 如果有 1 2 或 3 个值 则它只是平均值 但如果有 4 个值 它将排除最高值 5 个值将排除最高值和最低值 等等 我正在考虑某种窗口函数 但我不确定
  • 将自动递增值添加到只有一列的表中

    我需要创建一个基本上仅保留索引列表的表 因此 我创建了一个只有一个名为 id 的自动递增列的表 但是 我似乎无法隐式地将自动递增值添加到该表中 我知道通常当您在表中有这样一列 不仅仅是此列 时 您可以执行以下操作 插入表 col1 col2
  • 迁移问题:MS SQL > MySQL:插入缓冲区内存

    我在使用 MySQL Workbench 上的内置迁移工具时遇到问题 我正在将一个非常大的数据库从 MS SQL 2014 迁移到 MySQL MS SQL 服务器本地部署在我的 Windows 8 1 桌面上 MySQL 服务器在我的网络
  • SQLite 使用循环重新编号 ID

    您好 我有一个包含许多插入行的表 我需要按 id 对所有行重新编号并排序 我找到了这段代码 但它对我不起作用 SET i 100 UPDATE main Categories SET ID i i 1 WHERE Name White AL
  • PostgreSQL WHERE 计数条件

    我在 PostgreSQL 中有以下查询 SELECT COUNT a log id AS overall count FROM Log as a License as b WHERE a license id 7 AND a licens
  • 什么是更好的?子查询或内连接十个表?

    一个旧系统已抵达我们的办公室进行一些更改和修复 但它也存在性能问题 我们并不确切知道这种缓慢的根源是什么 当我们重构旧代码时 我们发现了几个具有以下模式的 sql 查询 出于示例目的 简化了查询 SELECT SELECT X FROM A
  • Postgres 按查询分组

    我正在尝试在 postgres 的查询中使用 group by 我无法让它按照我想要的方式工作 以便根据需要对结果进行分组 这是另一个堆栈问题的扩展我刚刚回答过的递归查询 https stackoverflow com questions
  • parent_id 是外键(自引用)并且为 null?

    浏览 Bill Karwin 的书 SQL Antipatterns 第 3 章 Naive Trees 邻接表 父子关系 有一个注释表的示例 CREATE TABLE Comments comment id SERIAL PRIMARY

随机推荐

  • 保存和恢复 ExpandableListActivity 的展开/折叠状态

    我有一个 ExpandableListActivity 使用 SimpleCursorTreeAdapter 当用户单击子元素时 它会启动另一个活动 当在新活动中按下后退按钮时 所有列表项都会再次折叠 如何保存 ExpandableList
  • 注意:使用未定义的常量 DB_HOST - 在第 31 行的 C:\xampp\htdocs\blog\system\functions.php 中假定为“DB_HOST”

    犯了几个错误 我一辈子都看不到自己在哪里失败了 下面是函数文件
  • 初始化 constexpr 静态类成员时出现编译器错误

    我用以下方式声明了一个类 class A struct B constexpr B uint8 t a uint8 t b a a b b bool operator const B rhs const if a rhs a b rhs b
  • 将列表中的连续数字组合在一起

    我有一个有序的 Python 表单列表 1 2 3 4 5 12 13 14 15 20 21 22 23 30 35 36 37 38 39 40 如何将列表中的连续数字分组在一起 像这样的一个团体 1 2 3 4 5 12 13 14
  • 在 Heroku 上安装私有 ssh 部署密钥

    我正在创建一个 Node js 应用程序 用作 Github 的 Web 挂钩 当推送更改时 它将自动部署某个私有存储库 为了使 webhook 应用程序尽可能高效 我想在部署时将私有存储库克隆并拉入 webhook 的 Heroku 实例
  • 在 matplotlib 颜色条中对齐刻度标签

    我有一个带有正值和负值的颜色条 这些值是自动生成的 我没有设置它们 不幸的是 减号破坏了文本的垂直对齐方式 如何将刻度标签中的所有文本向右对齐 或者在正数之前插入一个空格以使其看起来不错 您可以更改文本的对齐方式 可能需要稍微更改标签的 x
  • 为什么 Traversable 不能多次访问其元素?

    我记得在某处读过 像这样的类型不可能Traversable data Bar a Bar a deriving Show instance Functor Bar where fmap f Bar x Bar f x instance Fo
  • 如何获取数组项的类型?

    如果我有一个类型type foo Array lt name string test number gt 是否可以获取数组中值的类型 在本例中为接口 我知道有keyof要获取密钥 是否有类似的值 如果您正在寻找如何提取 name strin
  • 地图视图平滑缩放

    当我使用 MapController setZoom x 时 例如 从级别 5 缩放到 15 时 缩放执行得非常快 并且通常不会加载新级别的地图图块 这对用户来说看起来不太好 任何地图内置功能都可以将其更改为更慢的缩放 以便在达到 15 级
  • Android:编辑文本中密码的最小长度

    在android中 有没有简单的方法可以在edittext中设置最小密码长度 在 xml 中只有最大长度选项 而没有最小长度选项 设置 em 和宽度等选项来限制长度 但是什么时候设置最小长度呢 我在文档中找到了这个 DevicePolicy
  • 浮点型与双精度型

    是否存在比较 equals 两个浮点值之间将返回false如果你将它们比较DOUBLE但返回true如果你将它们与 FLOAT 进行比较 作为我的小组项目的一部分 我正在编写一些程序来比较任何给定类型的两个数值 我总共需要处理四种类型 do
  • Java 中的 double 到 long 无需转换

    我需要将 double 转换为 long 保留其二进制结构 而不是数值 只需更改类型 但保留二进制值不变 有没有一种本地方法可以做到这一点 有Double与 doubleToLongBits 和 doubleToLongRawBits Ja
  • 如何在 Hibernate 中使用唯一键而不是主键检索记录

    Using session load or session get 或任何其他方法org hibernate session 是否可以在hibernate中根据Unique列而不是PK列值获取记录 我的要求是我需要根据唯一列值而不是主键获取
  • 将 Arc 克隆为 Arc,其中 T 实现 U

    我觉得很奇怪 use std sync Arc trait Fruit struct Pear impl Fruit for Pear fn main let pear Arc new Pear let cloned Arc clone p
  • 在 Neo4j 中实现 Dijkstra 算法

    我对 Neo4j 很陌生 有人可以向我解释 请逐步 如何实现 Dijkstra 算法来找到两个节点之间的最短路径 是否可以简单地使用 Cypher 来完成它 我已经尝试过最短路径算法 但它很慢 MATCH from Location Loc
  • 为什么我不能反转 str::split 的结果?

    根据文档Split 有一个rev方法对结果的影响split在字符串上 fn main let mut length 0 let mut mult 1 for part in 1 30 split rev length mult part p
  • Eclipse p2:category.xml 和 site.xml 之间的区别

    p2 存储库创建 ant 任务 例如 eclipse publish featuresAndBundles 似乎采用指定类别信息的 site xml 或category xml 文件 我发现 eclipse 生成的 site xml 和ca
  • 圆形ViewPager。第一轮后碎片无法正常工作

    好的 所以我需要圆形 ViewPager 我真的很难实施它 现在我已经实现了它 并且就圆形滚动而言它运行良好 但我注意到一个问题 那就是 第一轮滚动片段不起作用后 我有三个片段 里面有一个按钮 按钮在第一轮有效 但当我回到第一页时按钮不起作
  • 有没有办法在 Eclipse 中自动生成 getter 和 setter?

    我正在研究一个新的Android项目 Java 并创建了一个带有大量变量的对象 由于我计划为所有这些添加 getter 和 setter 所以我想知道 是否有捷径Eclipse自动生成给定类中的 getter 和 setter 在所需类的源
  • 使用 JSONB 列内的值连接表

    有两个表 授权联系人 auth contacts userid varchar contacts jsonb contacts包含具有属性的联系人数组 contact id type discussion contact id varcha