Pergunta

Até onde eu sei, chaves estrangeiras (FK) são usadas para ajudar o programador a manipular os dados da maneira correta.Suponha que um programador já esteja fazendo isso da maneira certa, então realmente precisamos do conceito de chaves estrangeiras?

Existem outros usos para chaves estrangeiras?Estou faltando alguma coisa aqui?

Foi útil?

Solução

As chaves estrangeiras ajudam a reforçar a integridade referencial no nível dos dados.Eles também melhoram o desempenho porque normalmente são indexados por padrão.

Outras dicas

Chaves estrangeiras também podem ajudar o programador a escrever menos código usando coisas como ON DELETE CASCADE.Isso significa que se você tiver uma tabela contendo usuários e outra contendo pedidos ou algo assim, a exclusão de um usuário poderá excluir automaticamente todos os pedidos que apontam para esse usuário.

Não consigo imaginar projetar um banco de dados sem chaves estrangeiras.Sem eles, eventualmente você cometerá um erro e corromperá a integridade dos seus dados.

Eles não são obrigatório, estritamente falando, mas os benefícios são enormes.

Estou bastante certo de que FogBugz não possui restrições de chave estrangeira no banco de dados.Eu estaria interessado em saber como o Software Fog Creek A equipe estrutura seu código para garantir que nunca introduzirá uma inconsistência.

Um esquema de banco de dados sem restrições FK é como dirigir sem cinto de segurança.

Um dia você vai se arrepender.Não gastar tanto tempo extra com os fundamentos do design e a integridade dos dados é uma maneira segura de garantir dores de cabeça mais tarde.

Você aceitaria um código tão desleixado em seu aplicativo?Isso acessou diretamente os objetos membros e modificou diretamente as estruturas de dados.

Por que você acha que isso foi dificultado e mesmo inaceitável dentro das línguas modernas?

Sim.

  1. Eles mantêm você honesto
  2. Eles mantêm os novos desenvolvedores honestos
  3. Você pode fazer ON DELETE CASCADE
  4. Eles ajudam você a gerar bons diagramas que explicam as ligações entre as tabelas.

Pessoalmente sou a favor das chaves estrangeiras porque formaliza a relação entre as tabelas.Sei que sua pergunta pressupõe que o programador não está introduzindo dados que violariam a integridade referencial, mas já vi muitos casos em que a integridade referencial dos dados é violada, apesar das melhores intenções!

Restrições de chave pré-estrangeiras (também conhecidas como integridade referencial declarativa ou DRI) muito tempo foi gasto na implementação desses relacionamentos usando gatilhos.O fato de podermos formalizar o relacionamento por meio de uma restrição declarativa é muito poderoso.

@John - Outros bancos de dados podem criar índices automaticamente para chaves estrangeiras, mas o SQL Server não.No SQL Server, os relacionamentos de chave estrangeira são apenas restrições.Você deve definir seu índice em chaves estrangeiras separadamente (o que pode ser benéfico).

Editar:Gostaria de acrescentar que, IMO, o uso de chaves estrangeiras em suporte a ON DELETE ou ON UPDATE CASCADE não é necessariamente uma coisa boa.Na prática, descobri que a cascata de exclusão deve ser cuidadosamente considerada com base no relacionamento dos dados - por exemplo,você tem um pai-filho natural onde isso pode estar OK ou a tabela relacionada é um conjunto de valores de pesquisa.Usar atualizações em cascata implica que você está permitindo que a chave primária de uma tabela seja modificada.Nesse caso, tenho uma discordância filosófica geral de que a chave primária de uma tabela não deve mudar.As chaves devem ser inerentemente constantes.

Suponha que um programador já esteja fazendo isso da maneira certa

Fazer tal suposição parece-me uma péssima ideia;em geral, o software é fenomenalmente problemático.

E esse é o ponto, realmente.Os desenvolvedores não conseguem acertar as coisas, portanto, garantir que o banco de dados não seja preenchido com dados incorretos é uma coisa boa.

Embora em um mundo ideal, as junções naturais usariam relacionamentos (ou seja,Restrições FK) em vez de combinar nomes de colunas.Isso tornaria os FKs ainda mais úteis.

Sem uma chave estrangeira, como saber se dois registros em tabelas diferentes estão relacionados?

Acho que você está se referindo à integridade referencial, onde o registro filho não pode ser criado sem um registro pai existente, etc.Estas são frequentemente conhecidas como restrições de chave estrangeira - mas não devem ser confundidas com a existência de chaves estrangeiras.

Existe algum benefício em não ter chaves estrangeiras?A menos que você esteja usando um banco de dados de baixa qualidade, os FKs não são tão difíceis de configurar.Então, por que você teria uma política de evitá-los?Uma coisa é ter uma convenção de nomenclatura que diz que uma coluna faz referência a outra, outra é saber que o banco de dados está realmente verificando esse relacionamento para você.

Suponho que você esteja falando restrições de chave estrangeira impostas pelo banco de dados.Você provavelmente já está usando chaves estrangeiras, mas não informou ao banco de dados sobre isso.

Suponha que um programador esteja realmente fazendo isso da maneira certa, então realmente precisamos do conceito de chaves estrangeiras?

Teoricamente, não.No entanto, nunca houve um software sem bugs.

Bugs no código do aplicativo normalmente não são tão perigosos - você identifica o bug e o corrige, e depois disso o aplicativo funciona perfeitamente novamente.Mas se um bug permitir que dados corrompidos entrem no banco de dados, você ficará preso a ele!É muito difícil recuperar dados corrompidos no banco de dados.

Considere se um bug sutil em FogBugz permitiu que uma chave estrangeira corrompida fosse gravada no banco de dados.Pode ser fácil corrigir o bug e enviar rapidamente a correção aos clientes em uma versão de correção de bug.No entanto, como devem ser corrigidos os dados corrompidos em dezenas de bancos de dados? Correto o código pode quebrar repentinamente porque as suposições sobre a integridade das chaves estrangeiras não são mais válidas.

Em aplicações web você normalmente tem apenas um programa falando com o banco de dados, então há apenas um lugar onde bugs podem corromper os dados.Em um aplicativo corporativo, pode haver vários aplicativos independentes conversando com o mesmo banco de dados (sem mencionar as pessoas que trabalham diretamente com o shell do banco de dados).Não há como ter certeza de que todos os aplicativos seguem as mesmas suposições sem bugs, sempre e para sempre.

Se as restrições estiverem codificadas no banco de dados, então o pior que pode acontecer com os bugs é que o usuário receba uma mensagem de erro feia sobre alguns SQL restrição não satisfeita.Isso é muito É preferível permitir que dados corrompidos entrem em seu banco de dados corporativo, onde isso, por sua vez, interromperá todos os seus aplicativos ou apenas levará a todos os tipos de resultados errados ou enganosos.

Ah, e as restrições de chave estrangeira também melhoram o desempenho porque são indexadas por padrão.Não consigo pensar em nenhum motivo não para usar restrições de chave estrangeira.

FKs são muito importantes e devem sempre existir no seu esquema, a menos que você seja eBay.

Eu penso alguma coisa única em algum momento deve ser responsável por garantir relacionamentos válidos.

Por exemplo, Ruby nos trilhos não usa chaves estrangeiras, mas valida todos os relacionamentos.Se você acessar seu banco de dados apenas a partir desse aplicativo Ruby on Rails, tudo bem.

No entanto, se você tiver outros clientes gravando no banco de dados, sem chaves estrangeiras eles precisarão implementar sua própria validação.Você então tem duas cópias do código de validação que provavelmente são diferentes, o que qualquer programador deve ser capaz de dizer que é um pecado capital.

Nesse ponto, as chaves estrangeiras são realmente necessárias, pois permitem mover novamente a responsabilidade para um único ponto.

As chaves estrangeiras permitem que alguém que nunca viu seu banco de dados antes determine o relacionamento entre as tabelas.

Tudo pode estar bem agora, mas pense no que acontecerá quando seu programador sair e outra pessoa tiver que assumir.

As chaves estrangeiras permitirão que eles entendam a estrutura do banco de dados sem vasculhar milhares de linhas de código.

Até onde eu sei, chaves estrangeiras são usadas para ajudar o programador a manipular os dados da maneira correta.

Os FKs permitem que o DBA proteja a integridade dos dados contra a confusão dos usuários quando o programador falhar para fazer isso e, às vezes, para se proteger contra a trapalhada dos programadores.

Suponha que um programador já esteja fazendo isso da maneira certa, então realmente precisamos do conceito de chaves estrangeiras?

Os programadores são mortais e falíveis.Os FCs são declarativo o que os torna mais difíceis de estragar.

Existem outros usos para chaves estrangeiras?Estou faltando alguma coisa aqui?

Embora não tenha sido por isso que foram criados, os FKs fornecem dicas fortes e confiáveis ​​para ferramentas de diagramação e para construtores de consultas.Isso é repassado aos usuários finais, que precisam desesperadamente de dicas fortes e confiáveis.

Não são estritamente necessários, da mesma forma que os cintos de segurança não são estritamente necessários.Mas eles podem realmente evitar que você faça algo estúpido que bagunce seu banco de dados.

É muito melhor depurar um erro de restrição FK do que reconstruir uma exclusão que quebrou seu aplicativo.

Eles são importantes porque sua aplicação não é a única maneira pela qual os dados podem ser manipulados no banco de dados.Seu aplicativo pode lidar com a integridade referencial tão honestamente quanto desejar, mas basta um idiota com os privilégios certos para aparecer e emitir um comando de inserção, exclusão ou atualização no nível do banco de dados, e toda a aplicação de integridade referencial do seu aplicativo será ignorada.Colocar restrições FK no nível do banco de dados significa que, exceto se esse idiota escolher desabilitar a restrição FK antes de emitir seu comando, a restrição FK fará com que uma instrução de inserção/atualização/exclusão incorreta falhe com uma violação de integridade referencial.

Eu penso nisso em termos de custo/benefício...Em MySQL, adicionar uma restrição é uma única linha adicional de DDL.São apenas algumas palavras-chave e alguns segundos de reflexão.Esse é o único "custo" na minha opinião...

As ferramentas adoram chaves estrangeiras.As chaves estrangeiras evitam dados incorretos (ou seja, linhas órfãs) que podem não afetar a lógica ou funcionalidade de negócios e, portanto, passam despercebidos e aumentam.Também evita que desenvolvedores que não estão familiarizados com o esquema implementem partes inteiras de trabalho sem perceber que estão perdendo um relacionamento.Talvez tudo esteja ótimo dentro do escopo do seu aplicativo atual, mas se você perdeu alguma coisa e algum dia algo inesperado for adicionado (pense em relatórios sofisticados), você pode estar em uma situação em que terá que limpar manualmente os dados ruins que estão se acumulando desde o início do esquema sem uma verificação imposta ao banco de dados.

O pouco tempo que leva para codificar o que já está em sua cabeça quando você está juntando as coisas pode poupar a você ou a outra pessoa um monte de tristeza, meses ou anos no futuro.

A questão:

Existem outros usos para chaves estrangeiras?Estou faltando alguma coisa aqui?

Está um pouco carregado.Insira comentários, recuo ou nomeação de variáveis ​​no lugar de "chaves estrangeiras"...Se você já entende perfeitamente o que está em questão, “não adianta” para você.

Redução de entropia.Reduza o potencial de ocorrência de cenários caóticos no banco de dados.Temos dificuldade porque estamos considerando todas as possibilidades, então, na minha opinião, a redução da entropia é fundamental para a manutenção de qualquer sistema.

Quando fazemos uma suposição, por exemplo:cada pedido tem um cliente, essa suposição deve ser aplicada por algo.Nos bancos de dados, esse "algo" são chaves estrangeiras.

Acho que vale a pena compensar a velocidade de desenvolvimento.Claro, você pode codificar mais rápido sem eles e é provavelmente por isso que algumas pessoas não os usam.Pessoalmente, matei várias horas com NHibernar e alguma restrição de chave estrangeira que fica irritada quando executo alguma operação.NO ENTANTO, eu sei qual é o problema, então é menos problemático.Estou usando ferramentas normais e existem recursos para me ajudar a contornar isso, possivelmente até pessoas para ajudar!

A alternativa é permitir que um bug se infiltre no sistema (e com tempo suficiente, isso acontecerá) onde uma chave estrangeira não está definida e seus dados se tornam inconsistentes.Então, você recebe um relatório de bug incomum, investiga e "OH".O banco de dados está ferrado.Agora, quanto tempo isso vai levar para consertar?

Você pode ver as chaves estrangeiras como uma restrição que,

  • Ajude a manter a integridade dos dados
  • Mostre como os dados estão relacionados entre si (o que pode ajudar na aplicação da lógica e das regras de negócios)
  • Se usado corretamente, pode ajudar a aumentar a eficiência com que os dados são buscados nas tabelas.

Atualmente não usamos chaves estrangeiras.E na maior parte não nos arrependemos.

Dito isto - é provável que comecemos a usá-los muito mais num futuro próximo por vários motivos, ambos por motivos semelhantes:

  1. Diagramação.É muito mais fácil produzir um diagrama de um banco de dados se houver relacionamentos de chaves estrangeiras usados ​​corretamente.

  2. Suporte de ferramenta.É muito mais fácil construir modelos de dados usando Estúdio Visual 2008 que pode ser usado para LINQ para SQL se houver relacionamentos de chave estrangeira adequados.

Então, acho que o que quero dizer é que descobrimos que, se estivermos fazendo muito trabalho SQL manual (construir consulta, executar consulta, blahblahblah), as chaves estrangeiras não são necessariamente essenciais.Porém, quando você começa a usar as ferramentas, elas se tornam muito mais úteis.

A melhor coisa sobre restrições de chave estrangeira (e restrições em geral, na verdade) é que você pode confiar nelas ao escrever suas consultas.Muitas consultas podem se tornar muito mais complicadas se você não puder confiar no modelo de dados como "verdadeiro".

No código, geralmente obteremos uma exceção lançada em algum lugar - mas em SQL, geralmente obteremos apenas as respostas "erradas".

Em teoria, Servidor SQL poderia usar restrições como parte de um plano de consulta - mas, exceto pelas restrições de verificação para particionamento, não posso dizer que já testemunhei isso.

As chaves estrangeiras nunca foram explícitas (tabela FOREIGN KEY REFERENCES (coluna)) declaradas em projetos (aplicativos de negócios e sites de redes sociais) nos quais trabalhei.

Mas sempre houve uma espécie de convenção de nomenclatura de colunas que eram chaves estrangeiras.

É como com normalização de banco de dados - você tem que saber o que está fazendo e quais são as consequências disso (principalmente desempenho).

Estou ciente das vantagens das chaves estrangeiras (integridade dos dados, índice para coluna de chave estrangeira, ferramentas conscientes do esquema do banco de dados), mas também tenho medo de usar chaves estrangeiras como regra geral.

Além disso, vários mecanismos de banco de dados poderiam servir chaves estrangeiras de maneira diferente, o que poderia levar a erros sutis durante a migração.

Remover todos os pedidos e faturas do cliente excluído com ON DELETE CASCADE é o exemplo perfeito de um esquema de banco de dados bonito, mas mal projetado.

Sim.O ON DELETE [RESTRICT|CASCADE] evita que os desenvolvedores deixem os dados presos, mantendo-os limpos.Recentemente juntei-me a uma equipe de desenvolvedores Rails que não se concentrava em restrições de banco de dados, como chaves estrangeiras.

Felizmente, encontrei estes: http://www.redhillonrails.org/foreign_key_associations.html -- Os plug-ins RedHill on Ruby on Rails geram chaves estrangeiras usando o convenção sobre configuração estilo.Uma migração com ID do produto criará uma chave estrangeira para o eu ia no produtos mesa.

Confira outros ótimos plug-ins em Morro Vermelho, incluindo migrações envolvidas em transações.

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