Estou projetando um banco de dados com várias tabelas de pesquisa contendo possíveis atributos das entidades principais. Estou pensando em usar uma chave de 4 ou 5 caracteres para identificar esses valores de pesquisa em vez de um número inteiro de incremento automático para que, quando armazenar esses IDs de atributo nas tabelas principais, veja valores significativos em vez de apenas números aleatórios.
Quais são as implicações de desempenho de usar um campo de caractere como chave primária em vez de um número inteiro?
Estou usando o MySQL, se isso importa.
[Editar]
Essas tabelas de pesquisa têm novos registros adicionados com pouca frequência. Eles são mantidos manualmente e as chaves baseadas em caracteres também são criadas manualmente. Aqui está um exemplo:
CUISINES
ID Description
----- --------------
CHNSE Chinese
ITALN Italian
MXICN Mexican
Depende do seu motor. O senso comum é que as leituras são baratas, alguns bytes aqui e ali não afetarão significativamente o desempenho de um banco de dados de pequeno a médio porte.
Mais importante, depende dos usos para os quais você colocará a chave primária. As séries inteiras têm a vantagem de serem simples de usar e implementar. Eles também, dependendo da implementação específica do método de serialização, têm a vantagem de serem rapidamente deriváveis, já que a maioria dos bancos de dados apenas armazena o número de série em um local fixo, em vez de derivá-lo
Select max(ID)+1 from foo
instantaneamente.A questão é: como uma chave de 5 caracteres apresenta um "valor significativo" para você e para o aplicativo? Como esse valor é criado e leva mais ou menos tempo do que encontrar um número de série incremental. Embora haja uma quantidade trivial de espaço economizado em alguns números inteiros, a grande maioria dos sistemas ignorará essa economia de espaço.
Não há implicações de desempenho, exceto que o esquema de caracteres exige que nunca haja um mecanismo automático, pois suas "chaves" não podem ser derivadas. Para o seu domínio específico, não se preocupe com chaves artificiais e apenas use chinês, japonês e tailandês como nomes de chave. Embora você não possa garantir exclusividade sobre qualquer aplicativo possível, em seu escopo é muito mais razoável usá-los em vez de abreviações horríveis e forçadas de 5 caracteres. Não há impactos significativos no desempenho até chegar aos milhões de tuplas.
Como alternativa, se você estiver rastreando apenas por país de origem, e não por cozinhas regionais específicas (cantonesa, sichuana, siciliana, úmbria, calabresa, yucatecana, oaxaca etc.), poderá sempre usar os códigos ISO 3166 .
O espaço é barato . Quando você está falando de 10.000.000 de receitas nas quais está fazendo operações OLAP, talvez. Com 10.000 receitas, você está olhando para 150.000 de espaço.
Mas, novamente, depende. Se você tem muitos milhões de registros e está fazendo junções neles, faz sentido desnormalizar a pesquisa para algo tão trivial (em uma visão materializada). Para todos os propósitos práticos, a eficiência de junção relativa em uma máquina moderna entre uma chave de 5 caracteres e uma chave de comprimento variável é tão semelhante que é idêntica. Felizmente, vivemos em um mundo de abundância de CPU e abundância de disco. Os desagradáveis são muitas junções e ineficiência de consulta, em vez de comparação caractere por caractere. Com isso dito, sempre teste .
As coisas de P&T desse nível dependem tanto do banco de dados que as generalizações são extremamente difíceis. Crie dois modelos de amostra do banco de dados, preencha-os com os números estimados de registros e veja qual é o mais rápido. Na minha experiência, o tamanho do caractere não faz muita diferença em comparação com bons índices, boas configurações de memória e outros elementos críticos de ajuste de desempenho.
Eu acho que não há problema com o desempenho para tabelas raramente alteradas. Talvez você tenha problemas com design no futuro. Sugiro que você não use dados de negócios como chave primária devido a mudanças nos negócios. Use qualquer chave primária adicional para "vincular" tabelas em seu modelo. Quaisquer alterações nos negócios NÃO afetarão as tabelas relacionadas a esta.
A verdadeira questão é se o desempenho da consulta de banco de dados é significativo para seu aplicativo (tamanho dos dados). Se sua consulta levar microssegundos, economizar alguns desses microssegundos usando
Int
chaves não compensa a penalidade de legibilidade/manutenção. No entanto, se sua consulta levar alguns minutos, economizar alguns desses minutos pode valer a penaInt
.Abaixo está o motivo pelo qual acho que números inteiros podem economizar seu tempo de consulta (como uma porcentagem do tempo geral de consulta), mas os fundadores do SkySpark podem explicar isso melhor do que eu . Divulgação completa, meu empregador paga muito dinheiro ao SkySpark para usar seu banco de dados e estou tentando construir algo melhor/mais rápido.
Se você tiver muitos dados sequenciais (arquivos de log, séries temporais, análises, corpora de texto ou fala) que tenham links (relacionamentos) para qualquer uma de suas tabelas de pesquisa, você descobrirá que o espaço de armazenamento é crítico para a velocidade da consulta, apesar de @ A análise correta de Ballsun-Stanton de como o espaço é barato em $. Como a maior parte do tempo de consulta (para dados sequenciais) é gasta lendo o disco, o espaço não é barato em termos de tempo (como uma porcentagem do tempo geral de consulta). Portanto, a menos que seu RDB comprima/descompacte de forma automática e eficiente todas as chaves estrangeiras (chaves para registros relacionados), você desejará que todas as suas chaves sejam
Int
, que são as mais eficientes em termos de espaço em disco (e velocidade de leitura) por unidade de informação conteúdo (entropia). FYI MyISAM no MySql coloca restriçõessobre o que você pode fazer com linhas de dados compactados (somente leitura). Em outras palavras, inteiros incrementados automaticamente já são compactados tanto quanto é teoricamente possível , dada a limitação de tamanho mínimo baixo na maioria dos campos inteiros do banco de dados. E essa compressão vem sem:Há uma razão pela qual ORMs populares e eficientes, como o Django, são padronizados para auto-incrementar números inteiros para PKs e por que outras questões de SO chegaram à mesma conclusão.