O que aconteceu com as restrições do banco de dados?

45

Quando reviso modelos de banco de dados para RDBMS, geralmente me surpreendo ao encontrar pouca ou nenhuma restrição (exceto PK / FK). Por exemplo, a porcentagem costuma ser armazenada em uma coluna do tipo int (enquanto tinyint seria mais apropriado) e não há restrição CHECK para restringir o valor a 0..100. Da mesma forma, no SE.SE, as respostas que sugerem restrições de verificação geralmente recebem comentários sugerindo que o banco de dados é o local errado para restrições.

Quando pergunto sobre a decisão de não implementar restrições, os membros da equipe respondem:

  • Ou eles nem sabem que esses recursos existem em seu banco de dados favorito. É compreensível de programadores usando apenas ORMs, mas muito menos de DBAs que afirmam ter mais de 5 anos de experiência com um determinado RDBMS.

  • Ou que eles imponham essas restrições no nível do aplicativo, e duplicar essas regras no banco de dados não é uma boa ideia, violando o SSOT.

Mais recentemente, vejo cada vez mais projetos em que até chaves estrangeiras não são usadas. Da mesma forma, eu vi alguns comentários aqui no SE.SE que mostram que os usuários não se importam muito com a integridade referencial, permitindo que o aplicativo cuide dela.

Ao perguntar às equipes sobre a escolha de não usar os FKs, eles dizem que:

  • É o PITA, por exemplo, quando alguém precisa remover um elemento que é referenciado em outras tabelas.

  • NoSQL é um pouco, e não há chaves estrangeiras lá. Portanto, não precisamos deles no RDBMS.

  • Não é grande coisa em termos de desempenho (o contexto geralmente é de pequenos aplicativos da intranet trabalhando em pequenos conjuntos de dados, então, mesmo os índices não importariam muito; ninguém se importaria se o desempenho de um determinada consulta passa de 1,5 s para 20 ms.)

Quando olho para o aplicativo em si, observo sistematicamente dois padrões:

  • O aplicativo limpa adequadamente os dados e os verifica antes de enviá-los ao banco de dados. Por exemplo, não há como armazenar um valor 102 como uma porcentagem através do aplicativo.

  • O aplicativo supõe que todos os dados que vêm do banco de dados são perfeitamente válidos. Ou seja, se 102 vier como uma porcentagem, algo, em algum lugar, falhará ou simplesmente será exibido como está para o usuário, levando a situações estranhas.

  • Embora mais de 99% das consultas sejam feitas por um único aplicativo, com o tempo, os scripts começam a aparecer - os scripts são executados manualmente quando necessário ou os trabalhos agendados. Algumas operações de dados também são executadas manualmente no próprio banco de dados. Tanto os scripts quanto as consultas SQL manuais apresentam um alto risco de introduzir valores inválidos.

E aí vem minha pergunta:

Quais são os motivos para modelar bancos de dados relacionais sem restrições de verificação e, eventualmente, mesmo sem chaves estrangeiras?

Por que vale a pena, esta pergunta e as respostas que recebi (especialmente a interessante discussão com Thomas Kilian) me levaram a escrever uma artigo com minhas conclusões sobre o assunto das restrições do banco de dados .

    
por Arseni Mourzenko 29.11.2016 / 12:34
fonte

7 respostas

27

É importante distinguir entre diferentes casos de uso para bancos de dados.

O banco de dados comercial tradicional é acessado por vários aplicativos e serviços independentes e, talvez, diretamente por usuários autorizados. É fundamental ter um esquema bem pensado e restrições no nível do banco de dados, de modo que um erro ou supervisão em um único aplicativo não corrompa o banco de dados. O banco de dados é crítico para os negócios, o que significa que dados inconsistentes ou corruptos podem ter resultados desastrosos para os negócios. Os dados vão viver para sempre enquanto os aplicativos vêm e vão. Estes são os locais que podem ter um DBA dedicado para garantir a consistência e a integridade do banco de dados.

Mas também existem sistemas em que o banco de dados é totalmente integrado a um único aplicativo. Aplicativos autônomos ou aplicativos da Web com um único banco de dados integrado. Desde que o banco de dados seja acessado exclusivamente por um único aplicativo, você poderá considerar restrições redundantes, desde que o aplicativo funcione corretamente. Esses sistemas geralmente são desenvolvidos por programadores com foco no código do aplicativo e talvez não tenham uma compreensão profunda do modelo relacional. Se o aplicativo usar um ORM, as restrições poderão ser declaradas no nível ORM em um formato mais familiar aos programadores de aplicativos. Na extremidade inferior, temos aplicativos PHP que usam o MySQL, e por um longo tempo o MySQL não suportou restrições básicas, então você tinha para confiar na camada de aplicação para garantir a consistência.

Quando os desenvolvedores dessas diferentes origens se encontram, você tem um conflito cultural.

Neste mix, obtemos a nova onda de bancos de dados distribuídos de "armazenamento em nuvem". É muito difícil manter um banco de dados distribuído consistente sem perder o benefício de desempenho, portanto, esses bancos de dados geralmente evitam verificações de consistência no nível do banco de dados e basicamente permitem que os programadores lidem com isso no nível do aplicativo. Aplicativos diferentes têm requisitos de consistência diferentes e, embora o mecanismo de pesquisa do Googles priorize a disponibilidade em vez da consistência em seus servidores, estou disposto a apostar que o sistema de folha de pagamento é executado em um banco de dados relacional com muitas restrições.

    
por 30.11.2016 / 08:54
fonte
15

Atualmente, cada vez mais sistemas estão sendo executados em ambientes distribuídos, na nuvem e adotando a técnica de "scale out", em vez de "scale up". Isso é ainda mais importante se você estiver lidando com aplicativos on-line voltados para a Internet, como aplicativos de comércio eletrônico.

Dito isso, todos os aplicativos que devem ser dimensionados são restritos pelo Teorema da PAC , onde você deve escolher 2 de 3: Consistência, Disponibilidade e Tolerância à Partição (tolerância a falhas de rede).

Ao estudar o Teorema do CAP, você verá que não há muita escolha, mas escolher perder a Disponibilidade ou a Consistência, já que NUNCA pode realmente confiar na Rede 100% do tempo.

Em geral, vários aplicativos podem se dar ao luxo de ficar inconsistentes por algum tempo razoável, mas não podem se dar ao luxo de ficar indisponíveis para os usuários. Por exemplo, uma linha do tempo ligeiramente desordenada no Facebook ou no Twitter é melhor do que não ter acesso a uma linha do tempo.

Assim, vários aplicativos estão optando por deixar as restrições do banco de dados relacional, já que os bancos de dados relacionais são realmente bons em consistência, mas ao custo da disponibilidade.

Nota pessoal: Eu também sou antiquado e tenho trabalhado com sistemas financeiros antigos, nos quais a consistência de dados é um requisito de primeira classe na maior parte do tempo, e sou um grande fã de restrições de banco de dados. As restrições do banco de dados são a última linha de defesa contra anos e anos de mau desenvolvimento e equipes de desenvolvedores que vêm e vão.

"Est modus in rebus". Vamos continuar usando a consistência do "nível baixo" do banco de dados, onde a consistência é um requisito de primeira classe. Mas às vezes, deixá-lo ir não é um grande pecado depois de tudo.

- EDIT: -

Como há uma pequena edição na pergunta, há outro motivo legítimo para descartar restrições no banco de dados, IMO. Se você projetar um produto do zero, onde projetar seu sistema para suportar a tecnologia multi-banco de dados, você pode optar pelo menor denominador comum entre os bancos de dados suportados e eventualmente descartar o uso de quaisquer restrições, deixando toda a lógica de controle para sua aplicação.

Embora seja legítimo, também é uma área cinzenta para mim, porque atualmente não consigo encontrar nenhum mecanismo de banco de dados que não suporte restrições simples como a proposta na pergunta original.

    
por 29.11.2016 / 13:13
fonte
10

What are the reasons to model relational databases without check constraints and eventually even without foreign keys?

Primeiro, vamos esclarecer que estou falando aqui apenas sobre RDBMs, não sobre bancos de dados não-SQL.

Eu vi alguns bancos de dados sem FK ou PK, muito menos verificar restrições, mas para ser honesto eles são uma minoria. Talvez porque eu trabalhe em uma grande empresa.

Na minha experiência ao longo dos anos, posso dizer que algumas razões podem ser:

  • No caso de programadores iniciantes ou hobby , um ack de habilidades de modelagem
  • Uso extensivo ou quase exclusivo de ORMs sem contato real com o mundo do banco de dados
  • Ausência de um especialista em DBA ou outro modelador de dados em uma equipe ou projeto pequeno
  • Falta de envolvimento do especialista em DBA ou modelagem de dados nos primeiros estágios do desenvolvimento
  • Decisões de design deliberadas por parte da comunidade de desenvolvedores que considera que mesmo uma restrição de verificação que impõe que uma determinada coluna pode ter apenas 1,2 or 3 como um valor ou que a coluna "idade" deve ser >= 0 é "tendo lógica de negócios no banco de dados" . Mesmo cláusulas padrão são consideradas por alguns como lógica de negócios que não pertencem a um banco de dados, como você pode ver em várias perguntas e respostas recentes neste mesmo site. Os desenvolvedores que assim o consideram, obviamente, usariam o mínimo possível de restrições e farão tudo em código, até mesmo integridade referencial e / ou unicidade. Eu acho que esta é uma posição extrema.
  • Uso de RDBMs como armazenamentos de valor-chave , para emulação de comportamento não-SQL porque os requisitos são suficientemente simples para serem satisfeitos usando tabelas RDBMS como isolamentos de repositórios de valores-chave.
  • Supondo que o banco de dados sempre será gravado por "o aplicativo" e que ninguém precisará fazer um grande carregamento de dados ou editar ou inserir linhas por meio de um cliente SQL (em muitos casos, para corrigir problemas dados do aplicativo inserido). No melhor dos casos, sempre haverá outro aplicativo (além do "aplicativo") emitindo instruções DML para o banco de dados: um cliente SQL.
  • Não percebendo que os dados pertencem ao proprietário da empresa , não ao aplicativo.

Dito isso, gostaria de afirmar que RDBMS são softwares muito avançados que foram criados sobre os ombros dos gigantes e se mostraram muito eficientes para muitos requisitos de negócios, liberando os programadores de tarefas mundanas de impor a integridade referencial em uma série de arquivos binários ou arquivos de texto. Como sempre digo "não vivemos mais em um mundo de um único aplicativo e banco de dados" . No mínimo, um cliente SQL emitirá DMLs além do "aplicativo". Assim, o banco de dados deve se defender de erros humanos ou de programação em uma extensão razoável

Nesses tipos de requisitos bem conhecidos, em que o RDBMS não é bem dimensionado, por todos os meios adotam a tecnologia sem SQL . Mas está preocupando a proliferação de bancos de dados relacionais sem restrições onde milhares de linhas de código (geradas ou digitadas) se dedicam a impor o que o RDBMS deveria estar aplicando para você de maneiras mais eficientes.

    
por 30.11.2016 / 12:48
fonte
3

Existem restrições externas que impulsionam as decisões de tecnologia. Há apenas algumas situações em que você tem a necessidade ou o luxo de usar restrições de campo de banco de dados regularmente.

  1. As empresas têm desenvolvedores para aplicativos e banco de dados junto com o DBA, mas a maioria dos desenvolvedores não trabalha nesse tipo de ambiente. Eles fazem o máximo que podem no código. Além disso, alguns no lado do banco de dados não se envolvem nas regras de negócios. Eles estão principalmente lá para manter as coisas funcionando. Eles nunca vão pressionar por restrições no banco de dados. Tendo que lidar com aplicativos legados, integrações, migrações, fusões, aquisições, uma restrição de banco de dados pode ser a melhor solução.
  2. Sobrecarregar o banco de dados pode criar um gargalo que não é facilmente resolvido jogando mais máquinas no problema. Existem algumas situações em que a linguagem db não lida com alguns problemas de programação sem um grande impacto no desempenho, então você não pode planejar usar uma restrição para tudo. O Stackoverflow tem um servidor de banco de dados porque jogar 2 em um problema é um desafio.
  3. Teste automatizado - eles estão chegando lá, mas muitos desenvolvedores de db estão atrasados para a parte junto com as estruturas de teste / IDE.
  4. Implantação - mais coisas do db tornam isso mais complicado. O que acontece quando uma atualização no banco de dados de um cliente não é permitida porque existem dados que violam a restrição? Game over, a menos que você tenha uma maneira de resolver isso. No seu aplicativo, você pode decidir deixar o usuário lidar com isso conforme necessário ou instruir um administrador a fazer isso em um lote.
  5. Somente o app / api / service irá gravar dados no banco de dados, então por que incomodar? Isso acontece a maior parte do tempo e é por isso que não é comum.
  6. É bastante difícil lidar com erros de banco de dados sem que centenas de violações de restrições sejam resolvidas se tudo ficar fora de sintonia. A maioria fica feliz em fazer uma conexão e obter o nome da tabela correto.

Muitas equipes de desenvolvimento não querem dar muito controle a um desenvolvedor de banco de dados. Você tem sorte se conseguir mais de um, então as férias são muito divertidas. Não são muitos os que exigem controle absoluto sobre o domínio do banco de dados e assumem a responsabilidade por todas as consultas, regras de negócios, desempenho, disponibilidade, segurança e quais dados vão para o RAID. Aqui estão os procedimentos armazenados que você tem permissão para executar. Diverta-se. Nem pense em tocar em uma mesa.

    
por 30.11.2016 / 22:57
fonte
2

Este é um problema com o qual tenho lutado durante toda a minha carreira (quase 40 anos) e também quando escrevi meu SGBD. Uma descrição do meu ponto final está aqui: link . Então, aqui estão meus pensamentos.

  1. Em geral, a maioria das restrições é melhor tratada no aplicativo, de modo que diferentes partes do aplicativo possam impor restrições diferentes. Por exemplo, um código de estado pode não se aplicar em todas as jurisdições.
  2. Como um aparte beware de%. As marcações são > 100% ou você vai à falência:)
  3. As restrições são melhor descritas negativamente. ou seja, o que eles não podem ser, não o que deveriam ser. É sempre uma lista mais simples.
  4. As chaves estrangeiras são sempre boas e devem ser usadas. Ponto final. FK é uma das poucas construções semânticas em um SGBDR e muito útil. A maior dificuldade é decidir se permite que um valor seja pendurado se o FK for removido ou se usar linhas dependentes como uma razão para não excluir o registro FK.
  5. As restrições no mundo real geralmente são mais complexas do que uma restrição de valor de campo único.
  6. Algumas restrições, mesmo no nível do aplicativo, funcionam contra boas operações. por exemplo, a verificação agressiva de datas oculta erros em datas aparentemente boas. Você precisa de um erro do operador para obter uma medida de erros em datas que pareciam razoáveis.
por 06.12.2016 / 06:47
fonte
1

As restrições do banco de dados podem ter sido uma ideia inteligente, mas e um uso prático para elas? Tome sua restrição de porcentagem. Se você aplicar isso, seu banco de dados rejeitará felizmente as porcentagens inválidas. E depois? Você precisará da lógica de negócios para lidar com a exceção. O que na verdade significa que a lógica de negócios que está escrevendo uma porcentagem errada já falhou em outro lugar. Então, no curto: a única restrição prática que resta são aqueles que você vê (como PK / FK).

    
por 29.11.2016 / 13:32
fonte
1

Atualmente, com mais frequência, as pessoas estão usando software (por exemplo, Entity Framework) para gerar tabelas e colunas automaticamente. A ideia é que eles não precisam de habilidades de SQL, liberando a capacidade do cérebro.

As expectativas de que o software irá "resolver as coisas" são muitas vezes irrealistas e não criam as restrições que um humano faria.

Para obter melhores resultados, crie tabelas usando SQL e adicione restrições manualmente, mas às vezes as pessoas não podem fazer isso.

    
por 30.11.2016 / 13:13
fonte