【问题标题】:CREATE UNIQUE INDEX IF NOT EXISTS in postgreSQL如果 postgreSQL 中不存在,则创建唯一索引
【发布时间】:2014-07-10 10:32:30
【问题描述】:

我想在 PostgreSQL 中做类似的事情

CREATE UNIQUE INDEX IF NOT EXISTS

有什么想法吗?

【问题讨论】:

标签: sql postgresql ddl


【解决方案1】:

您可以通过此语句检查具有给定名称的索引是否存在。

如果您的索引名称是some_table_some_field_idx

SELECT count(*) > 0
FROM pg_class c
WHERE c.relname = 'some_table_some_field_idx' 
AND c.relkind = 'i';

从 Postgres 9.5 开始,您甚至可以使用

CREATE INDEX IF NOT EXISTS

【讨论】:

    【解决方案2】:

    只是另一种即用型解决方案。

    PostgreSQL v9.0+:

    DO $BLOCK$
    BEGIN
        BEGIN
            CREATE INDEX index_name ON table_name( column_name );
        EXCEPTION
            WHEN duplicate_table
            THEN RAISE NOTICE 'index ''index_name '' on table_name already exists, skipping';
        END;
    END;
    $BLOCK$;
    

    PostgreSQL v9.5+:

    CREATE INDEX IF NOT EXISTS index_name ON table_name( column_name );
    

    【讨论】:

      【解决方案3】:

      我已经用 PLSQL 函数包装了 a_horse_with_no_name 的代码,以便更方便地使用。我希望有人会觉得它有用。

      CREATE OR REPLACE FUNCTION create_index(table_name text, index_name text, column_name text) RETURNS void AS $$ 
      declare 
         l_count integer;
      begin
        select count(*)
           into l_count
        from pg_indexes
        where schemaname = 'public'
          and tablename = lower(table_name)
          and indexname = lower(index_name);
      
        if l_count = 0 then 
           execute 'create index ' || index_name || ' on ' || table_name || '(' || column_name || ')';
        end if;
      end;
      $$ LANGUAGE plpgsql;
      

      用法: select create_index('my_table', 'my_index_name', 'id');

      【讨论】:

      • 顺便说一句,很遗憾,CREATE INDEX IF NOT EXISTS 语法没有添加 CREATE TABLE IF NOT EXISTS(在 PG 9.1 中添加)!
      • 多列索引呢?
      【解决方案4】:

      为此,您需要一些程序代码,例如(未经测试!):

      do
      $$
      declare 
         l_count integer;
      begin
        select count(*)
           into l_count
        from pg_indexes
        where schemaname = 'public'
          and tablename = 'your_table'
          and indexname = 'your_index_name';
      
        if l_count = 0 then 
           execute 'create unique index public.your_index_name on public.your_table(id)';
        end if;
      
      end;
      $$
      

      【讨论】:

      • 问题是索引名虽然是唯一的(候选键的一部分),但不一定具有描述性;需要 pg_indexes.indkey[] 和 pg_attribute 的连接来找到具有不同名称的类似索引。
      • @joop:我同意,但是create index if not exists ...(如果有这样的语法)也不会检查。
      • 它需要一个语法挂钩 ala create index [aa] on bb(cc,dd) WHERE NOT EXISTS ( select ... FROM catalogs xx WHERE (something with {bb,cc,dd} ) ); 并且仍然存在共享相同 {bb,cc,dd} 值的唯一/非唯一索引的可能问题。和索引方法...
      【解决方案5】:

      如果您仍然停留在以前的版本中,我建议您不要使用 count,而只是直接在您的 if 条件下进行查询。使代码更简单。你可以试试这样:

      do 
      $$
      begin
      if not exists (
          select indexname
              from pg_indexes
          where schemaname = 'schemaname'
              and tablename = 'tablename'
              and indexname = 'indexname'
      )
      then
          create unique indexname (...);
      end if;
      end 
      $$;
      

      【讨论】:

        【解决方案6】:

        另一种支持多列索引的解决方案,基于@Kragh 的回答

        CREATE or replace FUNCTION create_index(_index text, _table text, VARIA
        
        DIC param_args text[]) RETURNS void AS
        $$
        declare 
           l_count integer;
        begin
            select count(*) into l_count
            from pg_indexes
            where schemaname = 'public'
                and tablename = lower(_table)
                and indexname = lower(_index);
        
            if l_count = 0 then
                EXECUTE format('create index %I on %I (%s)', _index, _table, array_to_string($3,','));
            end if;
        END;
        $$
        LANGUAGE plpgsql;
        

        然后你可以像使用任何其他 pg 函数一样使用它:

        select create_index('events_timestamp_type_idx', 'events', 'timestamp', 'type');

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-02
          • 1970-01-01
          • 2013-09-08
          • 1970-01-01
          • 2023-02-06
          • 2014-11-11
          • 2013-11-16
          • 2011-12-26
          相关资源
          最近更新 更多