Eu tenho várias tabelas nas quais os registros podem ser identificados exclusivamente com vários campos comerciais amplos. No passado, eu usei esses campos como um PK, com esses benefícios em mente:
- Simplicidade; não há campos estranhos e apenas um índice
- O agrupamento permite junções de mesclagem rápidas e filtros baseados em intervalo
No entanto, ouvi um argumento para criar uma IDENTITY INT
PK sintética e aplicar a chave comercial com uma UNIQUE
restrição separada . A vantagem é que o PK estreito gera índices secundários muito menores.
Se uma tabela não tiver outros índices além da PK, não vejo motivo para favorecer a segunda abordagem, embora em uma tabela grande provavelmente seja melhor supor que os índices possam ser necessários no futuro e, portanto, favorecer a PK sintética estreita . Estou faltando alguma consideração?
Aliás, não estou argumentando contra o uso de chaves sintéticas em data warehouses, apenas estou interessado em quando usar uma única PK ampla e quando usar uma PK estreita mais um amplo Reino Unido.
fonte
Respostas:
Não há desvantagem significativa usando a chave natural como o índice clusterizado
A desvantagem seria o aumento de divisões de páginas, pois as inserções de dados seriam distribuídas pelos dados, em vez de no final.
Onde você tem índices FKs ou NC, o uso de um índice clusterizado estreito, numérico e crescente tem vantagens. Você repete apenas alguns bytes de dados por entrada NC ou FK, e não a chave comercial / natural while.
Sobre o motivo, leia os 5 artigos do Google
Nota: evitei o uso de "chave primária".
Você pode ter o índice em cluster na chave substituta, mas manter a PK nas regras de negócios, mas como não em cluster. Apenas certifique-se de que o cluster seja único porque o SQL adicionará um "uniquificador" para fazê-lo.
Finalmente, pode fazer sentido ter uma chave substituta, mas não cegamente em todas as tabelas : muitas tabelas não precisam de uma ou onde uma chave composta das tabelas pai será suficiente
fonte
Embora eu arrisque afirmar o óbvio, um índice em uma chave substituta (um número de identificação) é útil se você precisar localizar as coisas pelo número de identificação. Os usuários não vão lidar com o número de identificação; eles vão lidar com texto legível por humanos. Portanto, você precisa repassar muito o texto e seu número de identificação, para que a interface do usuário possa exibir o texto e operar com o número de identificação.
Os dbms usarão esse tipo de índice para suportar chaves estrangeiras, se você as definir dessa maneira.
Às vezes, você pode melhorar o desempenho usando números de identificação como chaves estrangeiras, mas não é uma melhoria absoluta. Em nosso sistema OLTP, chaves estrangeiras que usam chaves naturais superaram as chaves estrangeiras usando números de identificação em um conjunto de testes de cerca de 130 (eu acho) consultas representativas. (Como as informações importantes geralmente são carregadas nas chaves, o uso de chaves naturais evitou muitas junções.) A aceleração mediana foi um fator de 85 (as junções usando números de identificação demoraram 85 vezes mais para retornar as linhas).
Os testes mostraram que as junções nos números de identificação não teriam desempenho mais rápido do que as leituras nas chaves naturais em nosso banco de dados até que determinadas tabelas atingissem muitos milhões de linhas. A largura da linha tem muito a ver com isso - linhas mais largas significam menos linhas cabidas em uma página, então você precisa ler mais páginas para obter 'n' linhas. Quase todas as nossas mesas estão em 5NF; a maioria das mesas é bastante estreita.
Quando as junções começam a executar leituras simples aqui , colocar tabelas e índices críticos em um disco de estado sólido pode nivelar o desempenho em centenas de milhões de linhas.
fonte
Eu tenho um banco de dados oltp inteiro projetado usando colunas de identidade para clustering + pk. Ele funciona muito rápido na inserção / procura, mas já vi alguns problemas:
1. a opção de preenchimento do índice é inútil porque as inserções acontecem apenas no final do índice
2. mais espaço de armazenamento. Eu tenho tabelas com dezenas de milhões de registros e 1 int ocupa espaço por si só. Cada tabela com uma coluna de identidade para o pacote tem que ter outro índice para buscas de negócios, para que seja necessário ainda mais armazenamento.
3. escalabilidade. Este é o pior problema. Como cada inserção vai para o final do índice, cada inserção enfatiza apenas o final do índice (alocação, io para gravações etc.). Usando uma chave comercial como chave de cluster, você pode distribuir as inserções uniformemente no índice. Isso significa que você acabou de eliminar um grande hotspot. Você pode facilmente usar mais arquivos para um índice, cada arquivo em uma unidade separada, cada unidade funcionando separadamente.
Comecei a mudar minhas tabelas de colunas de identidade para chaves naturais (talvez separadas para clustering e pk). Parece melhor agora.
Eu sugeriria o seguinte (pelo menos para um oltp db):
1. use como chave de cluster as colunas corretas na ordem certa para otimizar as consultas mais frequentes
2. use um pk nas colunas corretas que fazem sentido para sua tabela
Se a chave de cluster não é simples e contém chars (char [], varchar, nvarchar), acho que a resposta é 'depende', você deve analisar individualmente cada caso.
Eu mantenho o seguinte princípio: otimizar para a consulta mais comum, minimizando o pior cenário possível.
Eu quase esqueci um exemplo. Eu tenho algumas tabelas que se referem a si mesmas. Se essa tabela tiver uma coluna de identidade para sua chave primária, a inserção de uma linha poderá exigir uma atualização, e a inserção de mais de uma linha por vez pode ser difícil, se não impossível (depende do design da tabela).
fonte
Do ponto de vista do desempenho, a escolha de qual chave é a chave "primária" não faz nenhuma diferença. Não há diferença entre usar uma PRIMARY KEY e uma restrição UNIQUE para aplicar suas chaves.
O desempenho é determinado pela seleção e tipo de índices e outras opções de armazenamento e pela maneira como as chaves são usadas em consultas e códigos.
fonte