Pergunta

Fundo

eu tenho essas tabelas

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_code string (PK) |  |country_code string (PK)|
|address string           |  |name string             |
|name  string             |  +------------------------+
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_code string (PK)|
|name string              |
+-------------------------+

código_aeroporto é o IATA (Associação Internacional de Transporte Aéreo) código do aeroporto, você pode vê-los em suas etiquetas de bagagem quando viaja de avião.

enter image description here

Código do país é o Código de país padrão ISO 3166-1 A3, você pode vê-los nas Olimpíadas.

enter image description here

Código da moeda é o Código de moeda padrão IS0 417 de 3 caracteres, você pode vê-los em painéis de exibição de câmbio internacional.

enter image description here

Questões

Esses PKs naturais são bons o suficiente?

O uso de padrões respeitados mundialmente, aceitos por indústrias inteiras, é bom o suficiente para PKs?

Essas tabelas precisam de substitutos, não importa o que aconteça?

Foi útil?

Solução

Não, eles não querem.Essas chaves são definitivamente boas o suficiente!

Eles são únicos, não raramente vai mudar, e significativo, que é um avanço em relação a uma chave substituta.Essa é praticamente a definição de um bom PK.

As restrições sobre PKs serem imutáveis ​​​​e números inteiros não fazem parte do Modelo Relacional (Codd's) ou qualquer padrão SQL (ANSI ou outro).

Outras dicas

Eu penso precisar é uma palavra muito forte e, em sentido estrito, as tabelas provavelmente não precisar chaves substitutas.

No entanto, se fosse meu banco de dados, provavelmente adicionaria chaves substitutas de qualquer maneira.Talvez eu não queira necessariamente que o design do meu banco de dados dependa de vários terceiros (IATA, ISO), independentemente de quão estáveis ​​sejam seus padrões.Ou posso não querer depender de um padrão específico (existem outros padrões de código de moeda?Não sei).Eu provavelmente modelaria minhas tabelas com chaves substitutas assim:

+-------------------------+  +------------------------+
|Airport                  |  |Country                 |
|-------------------------|  |------------------------|
|airport_id       int (PK)|  |country_id     int (PK) |
|iata_airport_code string |  |iso_country_code string |
|icao_airport_code string |  +------------------------+
|faa_identifier    string |  
|address           string |  
|name              string |  
+-------------------------+

+-------------------------+
|Currency                 |
|-------------------------|
|currency_id int (PK)     |
|iso_currency_code string |
|name string              |
+-------------------------+

Em outras palavras, a menos que esses códigos padrão da indústria sejam inerentemente importante para meu aplicativo, eu não os usaria como PK de minhas tabelas.São apenas rótulos.A maioria das minhas outras tabelas provavelmente terá chaves substitutas de qualquer maneira, e essa configuração adicionaria consistência ao meu modelo de dados.O custo de “adicionar” as chaves substitutas é mínimo.

Atualização com base em alguns dos comentários:

Sem conhecer o contexto das tabelas de exemplo, é impossível saber a importância de coisas como códigos de aeroporto IATA para a aplicação que utiliza o banco de dados.Obviamente, se os códigos IATA são de importância central e são usados ​​de forma generalizada em toda a aplicação, pode ser a decisão correta, após análise adequada, usar os códigos como PK da tabela.

No entanto, se a tabela for apenas uma tabela de consulta usada em alguns cantos do aplicativo, a importância relativa dos códigos IATA pode não justificar um lugar tão proeminente na infraestrutura do banco de dados.Claro, você pode ter que fazer uma junção adicional em algumas consultas aqui e ali, mas esse esforço pode ser trivial em comparação com o esforço que seria necessário para fazer a pesquisa para garantir que você entende completamente as implicações de tornar os códigos IATA os campo de chave primária.Em alguns casos, não só não me importo, mas Eu não quero ter que me importar sobre os códigos IATA.O comentário de @James Snell abaixo é um exemplo perfeito de algo que talvez eu não queira me preocupar em afetar o PK de minhas mesas.

Além disso, a consistência no design é importante.Se você tiver um banco de dados com dezenas de tabelas com chaves substitutas projetadas de forma consistente e, em seguida, algumas tabelas de pesquisa que usam códigos de terceiros como PK, isso apresenta uma inconsistência.Isso não é de todo ruim, mas requer atenção extra na documentação e coisas que podem não ser garantidas.Eles estão Tabelas de pesquisa pelo amor de Deus, apenas usar uma chave substituta para consistência é perfeitamente aceitável.

Atualização com base em pesquisas adicionais:

Ok, a curiosidade me picou e resolvi fazer uma pesquisa sobre códigos de aeroportos IATA para me divertir, começando pelos links fornecidos na pergunta.

Acontece que os códigos IATA não são tão universais e oficiais como a questão faz parecer.De acordo com esta página:

A maioria dos países usa quatro caracteres Códigos ICAO, não os códigos da IATA, em suas publicações aeronáuticas oficiais.

Além disso, os códigos IATA e os códigos ICAO são distintos dos Códigos identificadores FAA, que são mais uma forma de identificar aeródromos.

Meu objetivo ao trazer isso à tona não é iniciar um debate sobre quais códigos são melhores ou mais universais ou mais confiáveis ​​ou mais abrangentes, mas mostrar exatamente por que projetar sua estrutura de banco de dados em torno de um identificador arbitrário de terceiros não é algo que eu escolheria fazer , a menos que haja um motivo comercial específico para fazê-lo.

Nesse caso, eu sinto meu banco de dados seria melhor estruturado, mais estável e mais flexível, renunciando aos códigos IATA (ou qualquer código potencialmente alterável de terceiros) como candidato a chave primária e usando uma chave substituta.Ao fazer isso, posso evitar quaisquer armadilhas potenciais que possam surgir devido à seleção da chave primária.

Embora ter chaves substitutas nos campos seja bom e não haja nada de errado com isso, algo a considerar pode ser o próprio tamanho da página de índice.

Como este é um banco de dados relacional, você fará muitas junções e ter uma chave substituta de tipo numérico pode facilitar o manuseio do banco de dados, ou seja,o tamanho da página de índice será menor e, portanto, mais rápido de pesquisar.Se este for um projeto pequeno, não importará e você sobreviverá sem problemas; no entanto, quanto maior o aplicativo, mais você desejará reduzir os gargalos.

Ter um BIGINT, INT, SMALLINT, TINYINT ou qualquer tipo de dados semelhante a um número inteiro pode evitar alguns problemas no futuro.

Apenas meus 2 centavos

ATUALIZAR:

Projeto pequeno – usado por algumas, talvez até algumas dezenas de pessoas.Projeto de demonstração em pequena escala, projeto para uso pessoal, algo para adicionar ao portfólio ao apresentar suas habilidades sem experiência, e assim por diante.

Projeto grande - usado por milhares, dezenas de milhares, milhões de usuários diariamente.Algo que você construiria para uma empresa nacional/internacional com uma enorme base de usuários.

Normalmente, o que acontece é que alguns registros selecionados são selecionados com frequência e o servidor armazena os resultados em cache para acesso rápido, mas de vez em quando você precisa acessar algum registro menos usado, momento em que o servidor teria que mergulhar no índice página.(no exemplo acima com os nomes dos aeroportos, as pessoas costumam voar em companhias aéreas domésticas, digamos Chichago -> Los Angeles, mas com que frequência as pessoas voam de Boston -> Zimbábue)

Se VARCHAR for usado, isso significa que o espaçamento não é uniforme, a menos que os dados tenham sempre o mesmo comprimento (ponto em que um valor CHAR é mais eficaz).Isso torna a pesquisa no índice mais lenta, e com o servidor já ocupado lidando com milhares e milhares de consultas por segundo, agora ele precisa perder tempo percorrendo um índice não uniforme e fazer a mesma coisa novamente nas junções (que é mais lento que seleções regulares em uma tabela não otimizada, tome DW como exemplo, onde há o mínimo de junções possível para acelerar a recuperação de dados).Além disso, se você usar UTF, isso também pode atrapalhar o mecanismo de banco de dados (já vi alguns casos).

Pessoalmente, por experiência própria, um índice organizado adequadamente pode aumentar a velocidade de uma junção em aproximadamente 70%, e fazer uma junção em uma coluna inteira pode acelerar a junção em até cerca de 25% (dependendo dos dados) .À medida que as tabelas principais começam a crescer e essas tabelas são usadas nelas, você prefere que um tipo de dados inteiro ocupe a coluna que possui alguns bytes em vez de ter um campo VARCHAR/CHAR que ocupará mais espaço.Tudo se resume a economizar espaço em disco, aumentando o desempenho e a estrutura geral de um banco de dados relacional.

Além disso, como James Snell mencionou:

As chaves primárias também devem ser imutáveis, algo que os códigos de aeroportos IATA definitivamente não são.Eles podem ser alterados conforme a vontade da IATA.

Então, levando isso em consideração, você prefere atualizar 1 registro vinculado a um número, em vez de atualizar esse registro mais todos os registros da tabela na qual você está ingressando.

Se você adotar a abordagem “Eu uso chaves substitutas o tempo todo”, você conseguirá contornar esse tipo de preocupação.Isso pode não ser bom porque é importante refletir um pouco sobre seus dados, mas certamente economiza muito tempo, energia e esforço.Se alguém adotasse uma aceitação a esta regra, os exemplos listados certamente se qualificariam porque seria necessário um quase “ato do Congresso” para fazer a mudança.

Consultas ad hoc de um banco de dados com essas chaves naturais são certamente úteis.Criar visualizações que fazem a mesma coisa incluindo tabelas de pesquisa também pode funcionar.Os bancos de dados modernos fazem um trabalho muito melhor com esse tipo de coisa, a ponto de provavelmente não importar.

Existem alguns casos específicos dos EUA, onde os padrões foram alterados drasticamente:O código postal expandiu de 5 a 9 dígitos, as abreviações dos estados para 2 letras consistentes e eliminou o período (lembra quando Illinois estava doente?), E a maior parte do mundo teve que lidar com o Y2K.Se você tem um aplicativo em tempo real com dados espalhados por todo o mundo contendo bilhões de registros, atualizações em cascata não são a melhor ideia, mas não deveríamos todos trabalhar em locais que enfrentam tais desafios?Com esse conjunto de dados, você poderia testá-lo por si mesmo e encontrar uma resposta mais definitiva.

Licenciado em: CC-BY-SA com atribuição
scroll top