PostgreSQL: Você pode criar um índice na definição CREATE TABLE?

105

Quero adicionar índices a algumas das colunas de uma tabela na criação. Existe uma maneira de adicioná-los à definição CREATE TABLE ou tenho que adicioná-los depois com outra consulta?

CREATE INDEX reply_user_id ON reply USING btree (user_id);
Xeoncross
fonte

Respostas:

118

Não parece haver nenhuma maneira de especificar um índice na CREATE TABLEsintaxe. PostgreSQL, no entanto, cria um índice para restrições exclusivas e chaves primárias por padrão, conforme descrito nesta nota :

O PostgreSQL cria automaticamente um índice para cada restrição única e restrição de chave primária para garantir a exclusividade.

Além disso, se você quiser um índice não exclusivo, precisará criá-lo em uma CREATE INDEXconsulta separada .

livrar
fonte
Obrigado, eu não sabia sobre a restrição exclusiva de criar um índice.
Xeoncross
Observe que o PostgreSQL suporta atualizações de esquema transacional - é uma boa idéia BEGIN / COMMIT em torno de suas instruções CREATE TABLE e CREATE INDEX, se você deseja que a criação da tabela global tenha sucesso ou falhe como um todo.
mindplay.dk
22

Não.

No entanto, você pode criar uniqueíndices no criar, mas isso é porque eles são classificados como restrições . Você não pode criar um índice "geral".

boêmio
fonte
6

Peter Krauss está procurando uma resposta canônica:

Há uma SINTAXE MODERNA (ano 2020), então explique e mostre exemplos, compatível com postgresql.org/docs/current/sql-createtable.html

Você está procurando uma definição de índice embutido , que não está disponível para PostgreSQL até a versão atual 12. Exceto a restrição UNIQUE / PRIMARY KEY, que cria o índice subjacente para você.

CRIAR A TABELA

[CONSTRAINT constraint_name] {CHECK (expression) [NO HHERIT] | UNIQUE (column_name [, ...]) index_parameters | PRIMARY KEY (column_name [, ...]) index_parameters |


O exemplo de sintaxe de definição de coluna inline (aqui SQL Server):

CREATE TABLE tab(
  id INT PRIMARY KEY,                            -- constraint
  c INT INDEX filtered (c) WHERE c > 10,         -- filtered index
  b VARCHAR(10) NOT NULL INDEX idx_tab_b,        -- index on column
  d VARCHAR(20) NOT NULL,
  INDEX my_index NONCLUSTERED(d)                 -- index on column as separate entry
);

db <> demonstração de violino

A lógica por trás de sua introdução é bastante interessante. O que são índices embutidos? por Phil Factor

Lukasz Szozda
fonte
Olá, resolvido (!). Você pode adicionar algo sobre um caso mais complexo, por exemplo b VARCHAR(10) NOT NULL INDEX idx_tab_b gin (b gin_trgm_ops).. como adicionar mais parâmetros sem repetir o nome da coluna?
Peter Krauss
@PeterKrauss O exemplo que forneci é para SQL Server, que não oferece suporte a gin_trgm_ops.
Lukasz Szozda
Olá @LukaszSzozda Para sintaxe, talvez você possa tentar transformar qualquer tipo de complexo CREATE INDEX idxName ON tableName USING MethodName (fieldName optionName);em sintaxe de definição de índice embutido . PS: esta questão é sobre PostgreSQL e não Microsoft-SQL-Server (veja as tags).
Peter Krauss
@PeterKrauss Estou totalmente ciente de que esta pergunta é sobre PostgreSQL. Acabei de dar a você um nome próprio para esse recurso e mostrar um exemplo de como isso poderia ser. Esperamos que mais RDBMS suportem índices inlinde no futuro :)
Lukasz Szozda