Pergunta

Há um debate saudável lá fora, entre aluguel e chaves naturais:

SO Post 1

SO Post 2

A minha opinião, que parece estar em linha com a maioria (é uma pequena maioria), é que você deve usar chaves substitutas menos que uma chave natural é completamente óbvia e garantia de não mudança. Então você deve impor a exclusividade na chave natural. Que meios substituto chaves quase todo o tempo.

Exemplo das duas abordagens, começando com uma tabela Empresa:

1: chave substituta: Table tem um campo de ID que é a PK (e uma identidade). nomes de empresas são obrigados a ser único em cada estado, por isso há uma restrição exclusiva lá.

2: chave Natural:. Tabela usa CompanyName e Estado como o PK - satisfaça tanto o PK e singularidade

Vamos dizer que o PK Empresa é usada em outros 10 mesas. Minha hipótese, sem números para apoiá-la, é que a abordagem chave substituta seria muito mais rápido aqui.

O argumento só convencer que eu vi para a chave natural é de muitos para muitos tabela que usa as duas chaves estrangeiras como uma chave natural. Eu acho que, nesse caso, faz sentido. Mas você pode ter problemas se você precisa refatorar; que está fora do escopo deste post eu acho.

Alguém viu um artigo que compara diferenças desempenho em um conjunto de tabelas que usam chaves substitutas vs. o mesmo conjunto de tabelas usando chaves naturais ? Olhando ao redor no SO e Google não produziu qualquer coisa de valor, apenas um monte de theorycrafting.


Atualização Importante : Eu comecei a construir um conjunto de tabelas de teste que a resposta a esta pergunta. Parece que este:

  • PartNatural - peças tabela que usa o PartNumber único como um PK
  • PartSurrogate - peças tabela que utiliza um ID (int, identidade) como PK e tem um índice exclusivo na PartNumber
  • Plant - ID (int, identidade) como PK
  • Engineer - ID (int, identidade) como PK

Cada parte é ligada a uma planta e cada instância de uma peça de cada planta é unido a um engenheiro. Se alguém tem um problema com este testbed, agora é a hora.

Foi útil?

Solução

Use ambos! Chaves naturais impedir a corrupção de banco de dados (inconsistência pode ser uma palavra melhor). Quando a chave natural "direito", (para eliminar linhas duplicadas) iria executar mal por causa do comprimento, ou o número de colunas envolvidas, para fins de desempenho, uma chave substituta podem ser adicionados, assim como para ser usado como chaves estrangeiras em outras tabelas em vez de a chave natural ... Mas a chave natural deve permanecer como uma chave alternativa ou índice exclusivo para evitar a corrupção de dados e banco de dados enforece consistência ...

A maior parte da hoohah (no "debate" sobre esta questão), pode ser devido a que é uma suposição falsa - que você tem que usar o chave primária para junta e chaves estrangeiras em outras tabelas. ISTO É FALSO. Você pode usar qualquer tecla de como o destino para as chaves estrangeiras em outras tabelas. Ele pode ser a chave primária, uma chave alternativa, ou qualquer índice único ou restrição única. E quanto a junta, você pode usar qualquer coisa para uma condição de junção, não tem sequer a ser uma chave, ou um idex, ou mesmo única !! (Embora se não é único você vai ter várias linhas no produto cartesiano ele cria).

Outras dicas

chaves naturais diferem das chaves substitutas em valor, não digite.

Qualquer tipo pode ser usado para uma chave substituta, como uma VARCHAR para o slug gerado pelo sistema ou qualquer outra coisa.

No entanto, os tipos mais usados ??para chaves substitutas são INTEGER e RAW(16) (ou o que digitar sua RDBMS faz uso para GUID de),

Comparando inteiros substitutos e inteiros naturais (como SSN) leva exatamente mesmo tempo.

VARCHARs Comparando fazer take agrupamento em conta e eles são geralmente mais do que números inteiros, que tornando-os menos eficientes.

Comparando um conjunto de dois INTEGER provavelmente também é menos eficiente do que a comparação de um único INTEGER.

Por tipos de dados pequenos em tamanho dessa diferença é provavelmente percentuais de porcentagens do tempo necessário para buscar páginas, índices transversal, base de dados acquite travas etc.

E aqui estão os números (em MySQL):

CREATE TABLE aint (id INT NOT NULL PRIMARY KEY, value VARCHAR(100));
CREATE TABLE adouble (id1 INT NOT NULL, id2 INT NOT NULL, value VARCHAR(100), PRIMARY KEY (id1, id2));
CREATE TABLE bint (id INT NOT NULL PRIMARY KEY, aid INT NOT NULL);
CREATE TABLE bdouble (id INT NOT NULL PRIMARY KEY, aid1 INT NOT NULL, aid2 INT NOT NULL);

INSERT
INTO    aint
SELECT  id, RPAD('', FLOOR(RAND(20090804) * 100), '*')
FROM    t_source;

INSERT
INTO    bint
SELECT  id, id
FROM    aint;

INSERT
INTO    adouble
SELECT  id, id, value
FROM    aint;

INSERT
INTO    bdouble
SELECT  id, id, id
FROM    aint;

SELECT  SUM(LENGTH(value))
FROM    bint b
JOIN    aint a
ON      a.id = b.aid;

SELECT  SUM(LENGTH(value))
FROM    bdouble b
JOIN    adouble a
ON      (a.id1, a.id2) = (b.aid1, b.aid2);

t_source é apenas uma tabela fictícia com linhas 1,000,000.

aint e adouble, bint e bdouble conter exactamente os mesmos dados, excepto que aint tem um inteiro como um PRIMARY KEY, enquanto adouble tem um par de dois inteiros iguais.

Na minha máquina, ambas as consultas funcionam por 14,5 segundos, +/- 0,1 segundos

Diferença de desempenho, se houver, está dentro das flutuações variar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top