Tornar um campo exclusivo o torna indexado?

10

Se eu fizer uma uniquerestrição em um campo, também preciso criar um índice nesse campo para obter um tempo de inserção escalável? Ou isso foi feito para mim (mesmo que o índice usado não seja acessível ao público?)

Especificamente, estou trabalhando com o Apache Derby para prototipagem, embora provavelmente o mude para o MySQL em um futuro semi-próximo. Também espero que exista algo no padrão SQL que diga algo sobre isso.

Nunca precisarei pesquisar por esse campo, portanto, prefiro não criar um índice inútil. Mas eu prefiro ter um índice inútil do que ter um O(n)tempo de inserção.

corsiKa
fonte
2
Pelo que sei, uma restrição exclusiva é implementada por trás usando um índice exclusivo. Você pode ver algumas opiniões sobre essa situação nesta pergunta: quando usar restrição exclusiva em vez de um índice exclusivo?
Marian
@ Marian obrigado por esse link. Foi muito perspicaz.
CorsiKa

Respostas:

2

--EDITAR--

Minha resposta original (abaixo) provavelmente não é útil para você, porque não trata da questão das uniquerestrições. Como outros já disseram, essas restrições geralmente são implementadas com um índice exclusivo implícito. Em casos especiais, isso pode não ser verdade (por exemplo, disable novalidatepara Oracle).

A pergunta poderia ser: é possível impor exclusividade sem um índice? De um modo geral, a resposta é que, em alguns casos, um Índice de Cluster significa que o índice e a tabela são o mesmo objeto.

--END EDIT--

Você disse "Prefiro ter um índice inútil do que ter um tempo de inserção de O (n)". Mas, em geral, os bancos de dados não têm tempo de inserção de O (n). Há dois casos a serem considerados:

  1. Uma tabela normal com ou sem índices:

    Novas linhas são despejadas na parte superior da pilha. O RDBMS provavelmente olha apenas para 1 bloco, portanto, não apenas O (1), mas O muito pequeno (1).

    Se a tabela tiver índices, um ponteiro para a linha será adicionado a cada um. Isso geralmente será uma operação O (log (n)).

  2. Uma tabela com algum tipo de cluster em andamento, por exemplo, uma tabela organizada por índice ou cluster para Oracle ou um índice clusterizado para SQL Server e outros:

    Novas linhas são inseridas em um bloco específico, o que pode causar a divisão ou transbordamento do bloco, mas aconteça o que acontecer, ainda é O (log (n)) ou melhor , causado pela árvore b ou estrutura semelhante usada para encontrar o bloco.

Jack diz que tenta topanswers.xyz
fonte
Mas a exclusividade sem um índice seria O(n)como você deve verificar a tabela inteira. É isso que estou tentando evitar.
CorsiKa
Esta é realmente a melhor resposta para esta pergunta !!! +1
RolandoMySQLDBA
@ Trick - sim, eu entendi errado no começo. Receio que o índice seja o preço que você paga pela restrição de exclusividade. Você pode usar um índice clusterizado no seu caso?
Jack diz que tente topanswers.xyz
11
@JackPDougless Posso usar um "índice" padrão e obter um O(lg n)tempo de inserção. Isso não é problema. Minha pergunta é se o sistema, sabendo que você precisa desse índice para obter um tempo de inserção decente, crie um índice para mim.
CorsiKa
2

CHAVE PRIMÁRIA> = ÚNICA> = ÍNDICE == CHAVE

Os dados do InnoDB são ordenados pelo PK. MyISAM PK age da mesma forma que UNIQUE.

INSERT deve adicionar uma "linha" a todo e qualquer índice (de qualquer tipo) que você tiver. Isso leva algum tempo. (Geralmente, não há tempo suficiente para importar.) Os índices são todos armazenados no formato BTree. Os blocos MyISAM BTree são de 1 KB; O InnoDB usa 16 KB.

A inserção no InnoDB atualiza a PK e os dados simultaneamente.

Inserir no MyISAM normalmente "anexa" os dados ao .MYD. Separadamente, ele adiciona uma linha ao PK (se houver).

INSERT deve primeiro verificar se não há chave duplicada para nenhuma chave PRIMARY ou UNIQUE. Isso é feito usando o índice. E, portanto, por que as Restrições de Chaves Exclusivas e Estrangeiras realmente criam índices. Isso é O (logN), mas geralmente CPU, não E / S, porque se o cache é eficiente.

Rick James
fonte
Você tem uma citação na especificação do InnoDB que afirma que uma UNIQUErestrição criará um índice sem que o usuário especifique uma a ser feita?
corsiKa
Hmmm ... Não, apenas anos de experiência.
Rick James
E aqui está uma maneira de testá-lo ... CRIE uma tabela sem nenhum índice secundário; SHOW TABLE STATUS - Index_length será 0. Em seguida, adicione um índice UNIQUE; O TABLE STATUS agora mostrará algo. (Pode ter que colocar uma quantidade não trivial de dados na tabela.)
Rick James
1

Para responder à pergunta em negrito: Sim, tornar um campo exclusivo indexa-o como a chave primária. De fato, eu discuti isso em outra questão com relação às Chaves Primárias com Nome Próprio para distingui-las de outras Chaves Exclusivas (Candidatas) .

Quanto às restrições, os índices são criados para você, para que o paradigma da restrição seja configurado. Você poderá remover índices duplicados, mesmo chaves UNIQUE, desde que a restrição que você criou não faça referência a outras chaves UNIQUE que você criou pessoalmente, além do paradigma de restrição.

Talvez você nunca precise procurar esse campo, mas o MySQL certamente terá que ser o caminho para determinar a validade das chaves e como executar as operações ON DELETE CASCADE e ON UPDATE CASCADE.

O índice UNIQUE simplesmente garante exclusividade de tuplas (singletons, pares, trigêmeos, ..., n-tuplas, etc) em todas as linhas da tabela.

Você pode remover esses índices duplicados, desde que você não quebre o paradigma de restrição que deseja ter na tabela.

RolandoMySQLDBA
fonte
11
Isso não responde à minha pergunta. Minha pergunta está relacionada ao tempo de inserção. Se você tiver uma restrição exclusiva, o sistema deverá garantir a exclusividade do campo antes de uma inserção - se não houver índice no campo, ele terá que pesquisar em toda a tabela ( O(n)). Se houver um índice, a pesquisa será muito mais rápida (provavelmente O(lg n)). Esse é o meu problema. Estou bem ciente da mecânica de integridade referencial, apenas estou preocupado (para fins desta pergunta) com o desempenho.
CorsiKa