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


46

Quando analiso modelos de banco de dados para RDBMS, geralmente fico surpreso ao encontrar poucas ou nenhuma restrição (além de PK / FK). Por exemplo, a porcentagem é frequentemente armazenada em uma coluna do tipo int(enquanto tinyintseria mais apropriado) e não há CHECKrestrição para restringir o valor ao intervalo de 0 a 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 para programadores que usam apenas ORMs, mas muito menos para DBAs que afirmam ter mais de 5 anos de experiência com um determinado RDBMS.

  • Ou que 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 mais e mais projetos em que nem chaves estrangeiras 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, deixando o aplicativo lidar com isso.

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

  • É PITA, por exemplo, quando é necessário remover um elemento que é referenciado em outras tabelas.

  • O NoSQL é ótimo e não há chaves estrangeiras lá. Portanto, não precisamos deles no RDBMS.

  • Não é um grande problema em termos de desempenho (o contexto geralmente são pequenos aplicativos Web da intranet trabalhando em pequenos conjuntos de dados; portanto, mesmo índices não importam muito; ninguém se importaria se o desempenho de uma determinada consulta passasse de 1,5 s a 20 ms.)

Quando olho para o próprio aplicativo, percebo 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 102como porcentagem através do aplicativo.

  • O aplicativo pressupõe que todos os dados provenientes do banco de dados sejam perfeitamente válidos. Ou seja, se 102vier como uma porcentagem, algo pode travar em algum lugar ou ele 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 - scripts executados manualmente quando necessário ou tarefas cron. Algumas operações de dados também são executadas manualmente no próprio banco de dados. Os scripts e as consultas manuais SQL têm um alto risco de introduzir valores inválidos.

E aqui vem a 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?


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


8
Eu sinto muito por você, mas parece que você já sabe por que as restrições são uma boa ideia; portanto, não há muito a acrescentar na forma de uma resposta. Observarei, no entanto, que a falta de restrições não é um fenômeno novo, já o vejo há décadas em bancos de dados projetados por desenvolvedores sem uma forte compreensão dos bancos de dados relacionais. Eu acho que raramente é uma decisão deliberada de design.
JacquesB

1
@ JacquesB: você pode postar uma resposta, uma vez que “eu a vejo há décadas” dá uma visão muito diferente da que eu tive de um fenômeno que apareceu há três ou quatro anos (desde que eu trabalhei em TI por menos de um ano). década, minha visão do fenômeno provavelmente está errada). Assim, as conclusões também seriam muito diferentes.
Arseni Mourzenko 29/11

1
Trabalhamos com muitos clientes. E embora implantar uma nova versão do nosso software seja uma tarefa fácil, atualizar todos os esquemas de banco de dados de todos os lugares é uma dor. É por isso que temos mais restrições em software. Ohh, sim, um pequeno valor para uma porcentagem geralmente não é uma boa ideia, porque as porcentagens podem ser frações.
Pieter B

1
Votação para reabrir esta questão, pois ela foi incorretamente fechada como "principalmente baseada em opiniões" quando as respostas até agora mostram que esse não é o caso.
David Arno

3
Estou com você 110%.
Periata Breatta

Respostas:


28

É importante distinguir entre diferentes casos de uso de 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. É essencial ter um esquema bem pensado e restrições no nível do banco de dados, para que um bug ou supervisão em um único aplicativo não corrompa o banco de dados. O banco de dados é essencial para os negócios, o que significa que dados inconsistentes ou corrompidos podem ter resultados desastrosos para os negócios. Os dados permanecerão para sempre enquanto os aplicativos vão e vêm. Esses são os locais que podem ter um DBA dedicado para garantir a consistência e integridade do banco de dados.

Mas também existem sistemas em que o banco de dados está totalmente integrado a um único aplicativo. Aplicativos independentes ou aplicativo da web com um único banco de dados incorporado. Desde que o banco de dados seja acessado exclusivamente por um único aplicativo, você pode 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 com uma compreensão profunda do modelo relacional. Se o aplicativo usar um ORM, as restrições poderão ser declaradas no nível do ORM de uma forma mais familiar aos programadores de aplicativos. No final, temos aplicativos PHP usando o MySQL e, por um longo tempo, o MySQL não suportava restrições básicas, portanto era necessário confiar na camada de aplicativos para garantir a consistência.

Quando desenvolvedores de diferentes origens se encontram, você entra em conflito cultural.

Nesse mix, temos 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 frequentemente evitam as verificações de consistência no nível do banco de dados e basicamente permitem que os programadores o manejem no nível do aplicativo. Aplicativos diferentes têm requisitos de consistência diferentes e, embora o mecanismo de pesquisa do Google priorize a disponibilidade sobre a 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.


5
! + 1 para mencionar o elefante na sala: a falsa premissa de que um aplicativo usa apenas um DB e que um DB é usado por apenas um aplicativo
Tulains Córdova

4
@ TulainsCórdova, pensei que o elefante na sala era o sistema de folha de pagamento do Google. :)
Machado

5
@ Machado Isso é genial: "Estou disposto a apostar que o sistema de folha de pagamento é executado em um banco de dados relacional com muitas restrições".
Tulains Córdova

2
Também é útil ter bancos de dados com restrições apropriadas, pois o código do aplicativo não é ACID.
Matthew Whited

3
Apenas para enfatizar o comentário feito por @MatthewWhited, não é possível que os aplicativos imponham alguns tipos de restrições entre linhas / entre tabelas sem executar o bloqueio e executar consultas extras. Um RDBMS pode fazê-lo a um custo muito menor.
David Aldridge

15

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

Dito isto, todos os aplicativos que devem escalar são limitados pelo Teorema do CAP , onde você deve escolher 2 de 3: Consistência, disponibilidade e tolerância a partições (tolerância a falhas de rede).

Ao estudar o teorema do CAP, você verá que não há muita escolha, mas optar por perder a disponibilidade ou a consistência, pois você NUNCA pode realmente confiar na rede 100% do tempo.

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

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

Nota pessoal: Também sou antiquado e tenho trabalhado com sistemas financeiros realmente antigos, nos quais a consistência dos dados é um requisito de primeira classe na maioria das vezes, e sou um grande fã das restrições do 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 de "baixo nível" do banco de dados, onde a consistência é um requisito de primeira classe. Mas, às vezes, deixar para lá não é um grande pecado, afinal.

- EDIT: -

Como há uma pequena edição na pergunta, há outro motivo legítimo para eliminar restrições no banco de dados, o IMO. Se você projetar um produto do zero, no qual projetou seu sistema para suportar a tecnologia de banco de dados múltiplo, pode optar pelo denominador menos comum entre os bancos de dados suportados e, eventualmente, abandonar 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 hoje não consigo encontrar nenhum mecanismo de banco de dados que não suporte restrições simples como a proposta na pergunta original.


"Hoje não consigo encontrar nenhum mecanismo de banco de dados que não suporte restrições simples como a proposta na pergunta original." O MySQL ainda suporta restrições CHECK?
Vincent Savard

@VincentSavard, talvez não seja exatamente o CHECK MS SQL, mas algum tipo de restrição: dev.mysql.com/doc/refman/5.7/en/constraint-invalid-data.html
Machado

@ Machado - não se trata de restrições específicas, mas de identificar quando as consultas incluem dados que não podem ser representados nos tipos apropriados. O que é uma melhoria distinta da situação anos atrás, quando o MySQL simplesmente ignorou silenciosamente esses valores.
Periata Breatta

1
O @PeriataBreatta, por outro lado, nunca entendi completamente por que o MySQL era o banco de dados OSS "de fato" escolhido pelos desenvolvedores de sites, quando o PostgreSQL estava totalmente disponível e era mais avançado. Talvez tenha sido mais fácil de instalar, não sei.
Machado

@machado - Não tenho certeza , mas sei que nos primeiros dias (em meados dos anos 90) eu costumava preferir o mysql ao postgres (que não foi renomeado para o postgresql até mais tarde) por causa de um equívoco que o postgres não suportava SQL (suas versões anteriores não - ele tinha sua própria linguagem de consulta chamada "postquel" - e eu não tinha me mantido atualizado com seu desenvolvimento, então não percebi que eles adicionaram suporte a SQL aproximadamente ao mesmo tempo em que o mysql ficou disponível). Se esse equívoco for comum, é possível que o mysql tenha se adiantado apenas por causa disso. E uma vez à frente, os efeitos da rede assumiram o controle.
Periata Breatta

10

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

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

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

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

  • No caso de iniciantes ou programadores de hobby , 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 DBA ou outro especialista em modelagem de dados em uma equipe ou projeto pequeno
  • Falta de envolvimento do DBA ou especialista em modelagem de dados nos primeiros estágios do desenvolvimento
  • Decisões deliberadas de design de uma parte da comunidade de desenvolvedores que considera que mesmo uma restrição de verificação que impõe que uma determinada coluna possa ter apenas 1,2 or 3um valor ou que a coluna "idade" deve ser ">= 0 está tendo lógica de negócios no banco de dados" . Algumas 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 site. Esses desenvolvedores que assim consideram, obviamente usariam o menor número possível de restrições e farão tudo no código, até integridade referencial e / ou unicidade. Eu acho que essa é uma posição extrema.
  • Uso de RDBMs como armazenamentos de valor-chave , ou para emular o comportamento não-SQL, porque os requisitos são simples o suficiente para serem satisfeitos usando as tabelas RDBMS como isolados de repositórios de valores-chave.
  • Supondo que o banco de dados sempre seja gravado pelo "aplicativo" e que ninguém precisará carregar muito dados, editar ou inserir linhas por meio de um cliente SQL (em muitos casos, para corrigir dados incorretos que o aplicativo inseriu). Na melhor das hipóteses, sempre haverá outro aplicativo (além do "app") 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 o RDBMS é um software muito avançado, construído sobre os ombros de gigantes e que se mostrou muito eficiente 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 de texto. Como sempre digo "não vivemos mais no mundo de um aplicativo e um banco de dados" . No mínimo, um cliente SQL emitirá DMLs além do "aplicativo". Portanto, o banco de dados deve se defender de erros humanos ou de programação em uma extensão razoável

Naqueles bem conhecidos tipos de requisitos em que o RDBMS não aumenta, 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 deve impor para você de maneiras mais eficientes.


3

Existem restrições externas que orientam as decisões tecnológicas. Existem poucas situações em que você tem a necessidade e / ou 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 do lado do banco de dados não se envolvem nas regras de negócios. Eles existem principalmente para manter as coisas funcionando. Eles nunca pressionarão por restrições no banco de dados. Ter que lidar com aplicativos herdados, integrações, migrações, fusões, aquisições e 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, lançando 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; portanto, você não pode planejar usar uma restrição para tudo. O Stackoverflow possui 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 banco de dados estão atrasados ​​para a festa junto com as estruturas de IDE / teste.
  4. Implantação - mais coisas de banco de dados tornam as coisas mais complicadas. 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? Fim de jogo, a menos que você tenha uma maneira de resolver isso. No seu aplicativo, você pode decidir permitir que o usuário lide com isso conforme necessário ou instruir algum administrador a fazer isso em lote.
  5. Somente o app / api / service gravará dados no banco de dados. Por que se preocupar? Isso acontece na maioria das vezes e é por isso que não é comum.
  6. Lidar com erros de banco de dados já é bastante difícil, sem centenas de violações de restrição, se tudo der errado. A maioria está feliz em fazer uma conexão e obter o nome da tabela correto.

Muitas equipes de desenvolvimento não desejam dar muito controle a um desenvolvedor de banco de dados. Você tem sorte se conseguir mais de um, por isso as férias são muito divertidas. Poucos 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 qual RAID. Aqui estão os procedimentos armazenados que você tem permissão para executar. Diverta-se. Nem pense em tocar em uma mesa.


2

Este é um problema com o qual lutei durante toda a minha carreira (quase 40 anos) e também ao escrever meu DBMS. Uma descrição do meu ponto final está aqui: http://unibase.zenucom.com . Então, aqui estão meus pensamentos.

  1. De um modo geral, a maioria das restrições é melhor manipulada no aplicativo, para 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 tenha cuidado com%. As marcações são> 100% ou você fica sem dinheiro :)
  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. Chaves estrangeiras são sempre boas e devem ser usadas. Ponto final. FK é uma das poucas construções semânticas em um RDBMS e muito útil. A maior dificuldade é decidir se um valor oscila se o FK for removido ou se as linhas dependentes são usadas para não excluir o registro do FK.
  5. As restrições no mundo real são geralmente 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 erro do operador para obter uma medida de erros em datas com aparência sensata.

1

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


15
Eu discordo educadamente disso. Se você realmente precisa de consistência de dados, as restrições de banco de dados são uma obrigação, especialmente se sua lógica de negócios estiver falhando. Da maneira como você está descrevendo o cenário, uma falha silenciosa ocorrerá, onde os danos causados ​​por uma porcentagem incorreta de falha serão propagados ainda mais no sistema. Se você tiver uma restrição de banco de dados sobre isso, falhará rapidamente e, assim, dará aos desenvolvedores de lógica de negócios a chance de ver o erro mais cedo e corrigir o sistema de lógica de negócios, em vez de permitir a entrada de dados corrompidos.
Machado

5
Meu entendimento é que, se a restrição percentual for violada, você não precisará lidar com essa exceção, porque essa violação indica que há um erro no seu código em primeiro lugar (alguém usou um número inteiro simples em vez de uma instância da Percentageclasse, ou há um erro na própria validação), em oposição a um caso excepcional (como uma conexão de rede desativada). Para mim, a violação deve levar ao HTTP 500 para um aplicativo Web ou uma falha para um aplicativo de desktop e, em seguida, deve ser registrado e corrigido.
Arseni Mourzenko 29/11

7
@ThomasKilian: não; exatamente o oposto. Os dados errados não serão recebidos, especificamente porque existem restrições no banco de dados. Se sua lógica de negócios estiver correta no código, você nunca violará essas restrições em primeiro lugar. Se um erro ocorrer no código, essas restrições o alertarão sobre esse bug, mantendo o banco de dados protegido contra sucatas.
Arseni Mourzenko

9
@ThomasKilian: Eu não acho que alguém esteja argumentando contra "acertar em primeiro lugar" - provavelmente é mais que alguém com um pouco de experiência sabe que é uma má idéia projetar um sistema na suposição de que você irá obter tudo certo da primeira vez e não erro ou erros vão sempre ocorrer durante a vida útil do sistema. As restrições de banco de dados garantem que um bug ou erro não corrompa o banco de dados.
JacquesB

3
@JacquesB Estou lutando contra moinhos de vento. Se você colocar a lógica de negócios no banco de dados, ela também pode falhar, em primeiro lugar, e não salvá-lo da mesma maneira. Mas (!) Agora você tem lógica de negócios onde não pertence. Acreditar que o banco de dados pode salvar sua lógica podre de negócios está simplesmente errado. A lógica no banco de dados deve seguir as mesmas regras que toda a lógica de negócios.
Qwerty_so 29/11

1

Atualmente, as pessoas costumam usar software (por exemplo, Entity Framework) para gerar tabelas e colunas automaticamente. A ideia é que eles não precisem de habilidades em SQL, liberando a capacidade do cérebro.

As expectativas de que o software "resolva as coisas" geralmente não são realistas e não criam as restrições que um ser humano criaria.

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


Algumas estruturas suportam a adição de PKs e FKs (semi) automaticamente, é claro.
David Aldridge
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.