Jon*_*len 3 postgresql database-metadata database-indexes
我有这个查询来获取表上的索引列表:
SELECT
ns.nspname as schema_name,
tab.relname as table_name,
cls.relname as index_name,
am.amname as index_type,
idx.indisprimary as is_primary,
idx.indisunique as is_unique
FROM
pg_index idx
INNER JOIN pg_class cls ON cls.oid=idx.indexrelid
INNER JOIN pg_class tab ON tab.oid=idx.indrelid
INNER JOIN pg_am am ON am.oid=cls.relam
INNER JOIN pg_namespace ns on ns.oid=tab.relnamespace
WHERE ns.nspname = @Schema AND tab.relname = @Name
Run Code Online (Sandbox Code Playgroud)
它似乎工作正常。但现在我需要对列列表进行查询,但我无法理解系统视图的工作方式。
具体来说,我正在寻找的是:
理想情况下,我想一次获得给定表的所有索引的上述项目。
请注意,我正在寻找的不仅仅是列名。
使用系统目录信息函数pg_get_indexdef(index_oid)获取完整信息(包括索引表达式列表) - 在查询中pg_index获取给定表的所有索引:
SELECT pg_get_indexdef(indexrelid) || ';' AS idx
FROM pg_index
WHERE indrelid = 'public.tbl'::regclass; -- optionally schema-qualified
Run Code Online (Sandbox Code Playgroud)
有关的:
如果您依赖非限定的表名(没有架构),则您依赖于当前search_path设置,并且可能会在不同架构中获得同名表的结果。
或者,您可以pg_attribute手动加入以获取单个列,如这些相关答案中所示:
关键因素是像这样加入:
FROM pg_index idx
LEFT JOIN pg_attribute a ON a.attrelid = idx.indrelid
AND a.attnum = ANY(idx.indkey)
AND a.attnum > 0
Run Code Online (Sandbox Code Playgroud)
手册关于pg_index.indkey:
这是一个
indnatts值数组,指示此索引索引哪些表列。例如,值1 3表示第一个和第三个表列组成索引条目。键列位于非键(包含)列之前。此数组中的零表示相应的索引属性是表列上的表达式,而不是简单的列引用。
添加AND a.attnum > 0在技术上不是必需的,因为没有a.attnum = 0. 但它使查询更清晰,它不会受到伤害。手册:
普通列从 1 开始编号。系统列,例如 oid,具有(任意)负数。
请注意,“列名列表”实际上也可以包含表达式。从 Postgres 11 开始,还有“包含”的列(那里没有表达式)。pg_get_indexdef()开箱即用地处理所有可能的并发症。
| 归档时间: |
|
| 查看次数: |
2038 次 |
| 最近记录: |