É necessário um índice para uma chave primária no SQLite?

130

Quando uma coluna inteira é marcada como chave primária em uma tabela SQLite, um índice também deve ser explicitamente criado para ela? O SQLite não parece criar automaticamente um índice para uma coluna de chave primária, mas talvez o indexe de qualquer maneira, dada a sua finalidade? (Eu estarei pesquisando nessa coluna o tempo todo).

A situação seria diferente para uma chave primária de cadeia?

Marek Jedliński
fonte

Respostas:

148

Faz isso por você.

Além das colunas INTEGER PRIMARY KEY, as restrições UNIQUE e PRIMARY KEY são implementadas criando um índice no banco de dados (da mesma maneira que uma instrução "CREATE UNIQUE INDEX" seria). Esse índice é usado como qualquer outro índice no banco de dados para otimizar consultas. Como resultado, geralmente não há vantagem (mas uma sobrecarga significativa) na criação de um índice em um conjunto de colunas que já estão sujeitas coletivamente a uma restrição UNIQUE ou PRIMARY KEY.

hvgotcodes
fonte
8
Na verdade, ele diz "O atributo PRIMARY KEY normalmente cria um índice UNIQUE na coluna ou colunas especificadas como PRIMARY KEY". No entanto, esse índice não é visível nos aplicativos de gerenciamento SQLite, é por isso que perguntei.
Marek Jedliński
1
É mencionado na sqlite_mastertabela com um nome que começa com sqlite_autoindex_.
dan04
2
Tarde, mas @NicolasZozol sim, você precisa criar um UNIQUEíndice (ou uma UNIQUErestrição) nos campos pai / referência, se ele não existir; ele é recomendado que a criança / campo referenciando (s) têm um índice (que geralmente não será exclusivo): ver aqui
TripeHound
2
Hmm, a seção SQL Data Constraints aqui diz: Na maioria dos casos , as restrições UNIQUE e PRIMARY KEY são implementadas criando um índice exclusivo no banco de dados. (As exceções são INTEGER PRIMARY KEY e PRIMARY KEYs nas tabelas SEM ROWID.) Então a resposta nem sempre é verdadeira?
Curiosidade divertida
3
Parece que o rowid IS está indexado, mas implementado diferentemente sqlite.org/lang_createtable.html#rowid Os dados para as tabelas rowid são armazenados como uma estrutura B-Tree contendo uma entrada para cada linha da tabela, usando o valor rowid como a chave ... para um registro com um rowid específico ... é cerca de duas vezes mais rápido que uma pesquisa semelhante feita especificando qualquer outro valor de indexação ou chave primária.
matreshkin
15

Se uma coluna estiver marcada INTEGER PRIMARY KEY, na verdade, será duas vezes mais rápida que uma pesquisa semelhante feita especificando qualquer outra PRIMARY KEY ou valor indexado . Isto é porque:

... todas as linhas nas tabelas SQLite têm uma chave inteira assinada de 64 bits que identifica exclusivamente a linha em sua tabela ... A pesquisa de um registro com um rowid específico ou de todos os registros com rowids dentro de um intervalo especificado é duas vezes mais rápido como uma pesquisa semelhante feita especificando qualquer outro valor PRIMARY KEY ou indexado.

Com uma exceção observada abaixo, se uma tabela rowid tiver uma chave primária que consiste em uma única coluna e o tipo declarado dessa coluna for "INTEGER" em qualquer combinação de maiúsculas e minúsculas, a coluna se tornará um alias para o rowid.

Essa coluna é geralmente chamada de "chave primária inteira". Uma coluna PRIMARY KEY apenas se torna uma chave primária inteira se o nome do tipo declarado for exatamente "INTEGER". Outros nomes de tipos inteiros como "INT" ou "BIGINT" ou "SHORT INTEGER" ou "UNSIGNED INTEGER" fazem com que a coluna da chave primária se comporte como uma coluna de tabela comum com afinidade de número inteiro e um índice exclusivo, não como um alias para o rowid.

Consulte: http://www.sqlite.org/lang_createtable.html#rowid

eiffel
fonte
8

Um banco de dados sempre cria silenciosamente um índice para uma chave primária exclusiva, para que possa verificar internamente se é única e eficiente.

Depois de criado, ele será usado quando necessário.

Obviamente, ele não será sempre agrupado, e você especifica geralmente no esquema se deseja que seja.

CashCow
fonte