【问题标题】:postgres get names of jsonb fields that comprise a unique indexpostgres 获取包含唯一索引的 jsonb 字段的名称
【发布时间】:2021-06-07 22:15:55
【问题描述】:

我正在使用 postgres 12.5。我一直在研究如何获取包含唯一索引的列的名称的答案。在结合 StackOverflow 和其他地方的一些答案后,我想出了这个解决方案

select i.relname as index_name,
    a.attname as column_name
from pg_class c
    inner join pg_index ix on c.oid=ix.indrelid
    inner join pg_class i on ix.indexrelid=i.oid
    inner join pg_attribute a on a.attrelid=c.oid and a.attnum=any(ix.indkey)
where c.oid='public.accounts'::regclass::oid
    and ix.indisunique is true
order by array_position(ix.indkey, a.attnum) asc

该解决方案适用于传统列类型的唯一索引,但不适用于 jsonb 列类型中字段的唯一索引。请参阅此 SQLFiddle 中的示例

http://sqlfiddle.com/#!17/22f6d/4

在那个 SQLFiddle 中,您可以看到如何创建表并创建两个不同的唯一索引。您可以看到上述查询如何获取包含唯一索引但未获取 jsonb 字段名称的所有常规列名。但你也可以看到 jsonb 字段上的唯一索引确实发挥了作用。

如何修改(或替换)上述查询以返回包含 jsonb 字段的复合唯一索引的列的名称?

附言请不要建议我将字段从 jsonb 移到专用列。这是我继承的遗留架构,需要使其按原样工作

【问题讨论】:

  • 我在小提琴“无法获取主机连接:无法从底层数据库获取连接!”时收到此错误。 (Postgresl 9.6)
  • 他们的网站一定已经关闭了。它现在正在工作。

标签: postgresql jsonb


【解决方案1】:

如果您有一个表达式的索引,则该表达式以解析节点树的形式存储在pg_indexindexprs 列中。

要将其解析为 SQL 字符串,您可以使用 pg_get_expr 函数:

SELECT i.relname AS index_name,
    coalesce(
       a.attname,
       pg_get_expr(ix.indexprs, ix.indrelid)
    ) AS indexed_expression
FROM pg_class c
    INNER JOIN pg_index ix ON c.oid = ix.indrelid
    INNER JOIN pg_class i ON ix.indexrelid = i.oid
    LEFT JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY (ix.indkey)
WHERE c.oid = 'public.accounts'::regclass
    AND ix.indisunique
ORDER BY array_position(ix.indkey, a.attnum) ASC;

    index_name     │    indexed_expression     
═══════════════════╪═══════════════════════════
 accounts_pkey     │ id
 accounts_expr_idx │ (data ->> 'member'::text)
(2 rows)

但我认为没有办法从 SQL 中的节点树中提取该表达式中使用的列名。

唯一可能的路径是通过pg_depend,其中存储了索引和基础表的列之间的依赖关系。

【讨论】:

  • 我不确定我是否理解您的回答。您在代码部分中显示的两行表明 SELECT 语句将获取 jsonb 字段的名称,但您还说,“但我认为没有办法提取列名”,这表明它是不可能。此外,SELECT 语句不适用于此 SQLFiddle sqlfiddle.com/#!17/22f6d/9,也不适用于我的本地开发环境和 Postgres 版本 13.1。但是必须有一种方法来获取它,因为 DBeaver 可以显示它。
  • “不起作用”是一个不充分的描述。 pg_get_expr 以文本形式获取索引表达式,但我不明白如何获取相关列。
猜你喜欢
  • 1970-01-01
  • 2018-07-28
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-15
  • 2017-10-14
  • 2021-07-20
相关资源
最近更新 更多