postgresql – 如果索引不存在则创建索引

前端之家收集整理的这篇文章主要介绍了postgresql – 如果索引不存在则创建索引前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在开发一个函数,允许我添加索引(如果它不存在).我遇到的问题是我无法获得要比较的索引列表.有什么想法吗?

这与使用此代码解决的列创建类似的问题:
https://stackoverflow.com/a/12603892/368511

Postgresql中的索引名称

>索引名称在单个数据库架构中是唯一的.
>索引名称不能与同一模式中的任何其他索引,(外部)表,(物化)视图,序列或用户定义的复合类型相同.
>同一模式中的两个表不能具有相同名称的索引. (逻辑上讲.)

如果您不关心索引的名称,可以让Postgres自动命名它:

CREATE INDEX ON tbl1 (col1)@H_502_15@ 
 

是(几乎)相同

CREATE INDEX tbl1_col1_idx ON tbl1 USING btree (col1);@H_502_15@ 
 

除了Postgres将避免命名冲突并自动选择下一个免费名称

tbl1_col1_idx 
tbl1_col1_idx2
tbl1_col1_idx3
...@H_502_15@ 
 

就试一试吧.但显然你不想创建多个冗余索引.所以盲目地创建一个新的不是一个好主意.

测试存在

Postgres 9.3或更早

一种非常简单的测试方法是将模式限定名称转换为regclass

SELECT 'myschema.myname'::regclass@H_502_15@ 
 

如果它抛出异常,则该名称是免费的.
或者,在DO声明中使用的测试相同而不抛出异常:

DO $$
BEGIN

IF NOT EXISTS (
    SELECT 1
    FROM   pg_class c
    JOIN   pg_namespace n ON n.oid = c.relnamespace
    WHERE  c.relname = 'my_name'
    AND    n.nspname = 'myschema' -- 'public' by default
    ) THEN

    CREATE INDEX my_name ON myschema.mytable (mycolumn);
END IF;

END$$;@H_502_15@ 
 

这不适用于CREATE INDEX CONCURRENTLY,因为该变量不能包装在外部事务中.见下文comment by @Gregory.

Postseres 9.0引入了DO声明.在早期版本中,您必须创建一个function才能执行相同操作.
有关pg_class in the manual的详细信息.
关于indexes in the manual的基础知识.

Postgres 9.4

您可以使用新函数to_regclass()进行检查而不抛出异常:

DO $$
BEGIN

IF to_regclass('myschema.my_name') IS NULL THEN
    CREATE INDEX my_name ON myschema.mytable (mycolumn);
END IF;

END$$;@H_502_15@ 
 

如果该名称的索引(或另一个对象)不存在,则返回NULL.细节:

> How to check if a table exists in a given schema

Postgres 9.5

现已推出:

CREATE INDEX IF NOT EXISTS ...@H_502_15@ 
 

这也适用于CREATE INDEX,如果不是EXISTS.

但是,per documentation

Note that there is no guarantee that the existing index is anything
like the one that would have been created.

这是对象名称的简单检查.适用于此处的所有变体.

猜你在找的Postgre SQL相关文章