Chaves estrangeiras - vincular usando chave substituta ou natural?

14

Existe uma prática recomendada para saber se uma chave estrangeira entre tabelas deve ser vinculada a uma chave natural ou a uma substituta? A única discussão que realmente encontrei (a menos que meu google-fu esteja faltando) é a resposta de Jack Douglas nesta pergunta , e seu raciocínio parece bom para mim. Estou ciente da discussão além da de que as regras mudam, mas isso seria algo que precisaria ser considerado em qualquer situação.

O principal motivo para perguntar é que eu tenho um aplicativo legado que faz uso de FKs com chaves naturais, mas há um forte impulso dos devlopers para mudar para um OR / M (NHibernate no nosso caso), e um fork já produziu alguns como alterar as alterações, por isso pretendo empurrá-las de volta aos trilhos usando a chave natural ou mover o aplicativo herdado para usar chaves substitutas para o FK. Meu intestino diz para restaurar o FK original, mas sinceramente não tenho certeza se esse é realmente o caminho certo a seguir.

A maioria de nossas tabelas já tem uma chave substituta e uma chave natural já definidas (embora restrição exclusiva e PK), portanto, adicionar colunas extras não é um problema para nós nesta seguradora. Estamos usando o SQL Server 2008, mas espero que isso seja genérico o suficiente para qualquer banco de dados.

Chris J
fonte

Respostas:

15

Nem o SQL nem o modelo relacional são perturbados por chaves estrangeiras que fazem referência a uma chave natural. De fato, referenciar chaves naturais geralmente melhora drasticamente o desempenho. Você ficaria surpreso com a frequência com que as informações necessárias estão completamente contidas em uma chave natural; referenciar essa chave negocia uma junção para uma tabela mais ampla (e consequentemente reduz o número de linhas que você pode armazenar em uma página).

Por definição, as informações que você precisa estão sempre completamente contidas na chave natural de cada tabela de "pesquisa". (O termo tabela de pesquisa é informal. No modelo relacional, todas as tabelas são apenas tabelas. Uma tabela de códigos postais dos EUA pode ter linhas com esta aparência: {AK, Alaska}, {AL, Alabama}, {AZ, Arizona} etc. A maioria das pessoas chama isso de tabela de pesquisa.)

Em grandes sistemas, não é incomum encontrar tabelas com mais de uma chave candidata. Também não é incomum que as tabelas que atendem a uma parte da empresa façam referência a uma chave candidata e as tabelas que atendem a outra parte da empresa façam referência a uma chave candidata diferente. Esse é um dos pontos fortes do modelo relacional e faz parte do modelo relacional que o SQL suporta muito bem.

Você terá dois problemas ao fazer referência a chaves naturais em tabelas que também possuem uma chave substituta.

Primeiro, você surpreenderá as pessoas. Embora eu geralmente faça um forte lobby pelo Princípio da Menor Surpresa , essa é uma situação em que não me importo de surpreender as pessoas. Quando o problema é que os desenvolvedores ficam surpresos com o uso lógico de chaves estrangeiras, a solução é educação, não redesenho.

Segundo, os ORMs geralmente não são projetados com base no modelo relacional e, às vezes, incorporam suposições que não refletem as melhores práticas. (De fato, eles geralmente parecem ter sido projetados sem a participação de um profissional de banco de dados.) Exigir um número de identificação em todas as tabelas é uma dessas suposições. Outro está assumindo que o aplicativo ORM "possui" o banco de dados. (Portanto, é gratuito criar, excluir e renomear tabelas e colunas.)

Trabalhei em um sistema de banco de dados que serviu dados para centenas de programas aplicativos escritos em pelo menos duas dúzias de idiomas durante um período de 30 anos. Esse banco de dados pertence à empresa, não a um ORM.

Uma bifurcação que introduz alterações de última hora deve ser uma barreira.

Avaliei o desempenho com chaves naturais e substitutas em uma empresa em que trabalhava. Há um ponto de inflexão no qual as chaves substitutas começam a superar as chaves naturais. (Presumindo que não haja esforço adicional para manter alto o desempenho da chave natural, como particionamento, índices parciais, índices baseados em funções, espaços de tabela extras, usando discos de estado sólido, etc.) Pelas minhas estimativas para essa empresa, eles atingirão esse ponto de inflexão em por volta de 2045. Enquanto isso, eles obtêm melhor desempenho com chaves naturais.

Outras respostas relevantes: No Esquema do Banco de Dados Confuso

Mike Sherrill 'Recolha de gatos'
fonte
5

A principal razão pela qual suporte chaves substitutas é que as chaves naturais geralmente estão sujeitas a alterações e isso significa que todas as tabelas relacionadas devem ser atualizadas, o que pode sobrecarregar o servidor.

Nos últimos 30 anos, tenho usado uma variedade de bancos de dados em muitos tópicos, a verdadeira chave natural é frequentemente bastante rara. As coisas são supostamente únicas (SSN) não são, as coisas que são únicas em um determinado momento podem se tornar não únicas mais tarde e algumas coisas como endereços de e-mail e números de telefone podem ser únicas, mas podem ser reutilizadas para pessoas diferentes posteriormente encontro. É claro que algumas coisas simplesmente não têm um bom identificador único, como nomes de pessoas e empresas.

Para evitar junções usando uma chave natural. Sim, isso pode acelerar as instruções de seleção que não precisam das junções, mas fará com que os locais onde você ainda precisa das junções sejam mais lentos, pois as junções int geralmente são mais rápidas. Provavelmente, também diminuirá as inserções e exclusões e causará problemas de desempenho nas atualizações quando a chave for alterada. Consultas complexas (que são mais lentas de qualquer maneira) serão ainda mais lentas. Portanto, consultas simples são mais rápidas, mas relatórios e consultas complexas e muitas ações no banco de dados podem ser mais lentas. É um ato de equilíbrio, que pode mudar de uma maneira ou de outra, dependendo de como o banco de dados é consultado.

Portanto, não há uma resposta única. Depende do seu banco de dados e como ele será consultado e que tipo de informação é armazenada nele. Pode ser necessário fazer alguns testes para descobrir o que funciona melhor em seu próprio ambiente.

HLGEM
fonte
1
"... chaves naturais estão sujeitas a alterações ..." - então elas não são chaves muito boas! Se um atributo está mudando frequentemente, não o use como chave (para várias definições de "frequentemente", é claro). Fabian Pascal argumentou que existem quatro critérios para escolher uma chave: familiaridade, irredutibilidade, estabilidade e simplicidade. Às vezes, você as troca pela simplicidade de uma chave substituta. Como HLGEM colocou: "Portanto, não existe uma resposta única para todos".
Greenstone Walker
1
@GreenstoneWalker, eu concordaria que você não deveria colocá-la como chave na época, mas muitas vezes você não tem uma chave que atenda aos quatro critérios e precisa seguir o que é único. E quando a exclusividade é uma chave copmposite, o problema pode ser ainda maior em termos de desempenho quando você precisa ter as junções.
HLGEM
-4

Se você não souber a resposta, vá com o substituto. Aqui está o porquê - se forem feitas suposições sobre regras de negócios, e essas suposições forem falsas ou as regras mudarem, seus dados serão lixo. Aqui está um exemplo:

Pessoa, função, PersonRole

A regra de negócios atual afirma que uma Pessoa tem uma Função. Você cria uma tabela que vincula Person e Role em que PersonRole (PersonName, PersonBirthDate, PersonMotherMaidenName, ..., RoleCode)

Agora você é um verdadeiro purista quando se trata de Chaves Naturais! Mas, falando sério, e se a organização decidir que uma pessoa agora pode assumir vários papéis? Quais são os efeitos posteriores do suporte à mudança nas necessidades dos negócios?

philn5d
fonte
2
E você não tem esses problemas com chaves substitutas? Por favor, mostre-nos como.
Colin 't Hart
4
O exemplo dado não parece demonstrar nada relevante para a discussão.
mustaccio