Devo definir as relações entre tabelas no banco de dados ou apenas no código?

60

Na minha experiência, muitos dos projetos que li no passado não tinham definições de relacionamento no banco de dados, mas apenas no código-fonte. Então, eu estou querendo saber quais são as vantagens / desvantagens de definir relações entre tabelas no banco de dados e no código-fonte? E a questão mais ampla é sobre outros recursos avançados em bancos de dados modernos, como cascata, gatilhos, procedimentos ... Há alguns pontos em meus pensamentos:

No banco de dados:

  • Corrija os dados do design. Evite erros de aplicativo que podem causar dados inválidos.

  • Reduza o ida e volta da rede para o aplicativo ao inserir / atualizar dados, pois o aplicativo precisa fazer mais consultas para verificar a integridade dos dados.

No código fonte:

  • Mais flexível.

  • Melhor ao escalonar para vários bancos de dados, pois às vezes a relação pode ser entre bancos de dados.

  • Mais controle sobre a integridade dos dados. O banco de dados não precisa verificar toda vez que o aplicativo modifica os dados (a complexidade pode ser O (n) ou O (n log n) (?)). Em vez disso, é delegado ao aplicativo. E acho que lidar com a integridade dos dados no aplicativo levará a mensagens de erro mais detalhadas do que usar o banco de dados. Por exemplo: quando você cria um servidor de API, se definir as relações no banco de dados, e algo der errado (como a entidade referenciada não existe), você receberá uma Exceção SQL com uma mensagem. A maneira mais simples será retornar 500 ao cliente, indicando que há um "erro interno do servidor" e o cliente não terá idéia do que está acontecendo de errado. Ou o servidor pode analisar a mensagem para descobrir o que está errado, o que é uma maneira feia e propensa a erros na minha opinião. Se você deixar o aplicativo lidar com isso,

Mais alguma coisa?

Edit: como Kilian aponta, meu argumento sobre desempenho e integridade de dados é muito equivocado. Então eu editei para corrigir o meu ponto lá. Entendo perfeitamente que deixar o banco de dados lidar com isso será uma abordagem mais eficiente e robusta. Por favor, verifique a pergunta atualizada e pense sobre isso.

Edit: obrigado a todos. As respostas que recebi apontam que as restrições / relações devem ser definidas no banco de dados. :). Tenho mais uma pergunta, pois ela está fora do escopo desta questão, acabei de postá-la como uma pergunta separada: Manipular erro de banco de dados no servidor API . Por favor, deixe algumas idéias.

Yoshi
fonte
4
"como o aplicativo precisa fazer mais consultas para verificar a integridade dos dados." Não necessariamente. Se o banco de dados estiver totalmente sob o controle de seu aplicativo, verificações extras da integridade dos dados poderão ser uma programação excessivamente defensiva. Você não precisa necessariamente deles; basta testar seu aplicativo adequadamente para garantir que ele faça apenas alterações válidas no banco de dados.
9
Há uma coisa que você nunca deve esquecer: a menos que todos os envolvidos escrevam um software perfeito, se as verificações estiverem no software, uma dessas verificações falhará e levará a restrições não sendo impostas. Não é uma questão de se, mas de quando. Isso leva a erros difíceis de reproduzir e a longas horas de massagem nos dados para ajustar novamente as restrições impostas pelo software.
Dabu
10
Algo que vale a pena mencionar ... depois de introduzir problemas de integridade no seu banco de dados, é possível abrir a caixa de Pandora. É um pesadelo reintroduzir a integridade em um banco de dados cheio de anomalias. Manter controles rígidos no banco de dados pode ser um aborrecimento, mas economizará muita dor a longo prazo.
DanK 26/10/16
3
No código fonte: você acaba escrevendo a maior parte de um banco de dados.
Blrfl
7
Certa vez, perguntei a um programador muito talentoso uma pergunta semelhante que ele me disse: "É como freios em um carro. O objetivo não é tornar o carro mais lento, mas permitir que ele vá mais rápido e mais seguro". Claro que é possível operar sem restrições, mas se os dados ruins de alguma forma entra, ele pode causar um acidente grave
mercurial

Respostas:

70

TL; DR: As restrições de relacionamento devem estar no banco de dados.


Seu aplicativo não é grande o suficiente.

Você está correto, de fato, que a imposição de relacionamentos entre bancos de dados pode exigir a imposição deles no aplicativo.

Gostaria de salientar, no entanto, que você deve primeiro verificar a documentação do software de banco de dados que está usando e verificar as ofertas de produtos existentes. Por exemplo, existem ofertas de cluster sobre Postgres e MySQL.

E mesmo se você acabar precisando ter alguma validação na aplicação, não deitar fora o bebé com a água do banho . Afinal, quanto menos você precisar fazer, melhor estará.

Finalmente, se você estiver preocupado com problemas futuros de escalabilidade, receio que seu aplicativo precise sofrer alterações significativas antes que possa ser dimensionado de qualquer maneira. Como regra geral, toda vez que você cresce 10x, você precisa redesenhar ... então não vamos gastar muito dinheiro para não antecipar problemas de escalabilidade e, em vez disso, use dinheiro para realmente chegar ao ponto em que você tem esses problemas.

Seu aplicativo não está correto o suficiente.

Qual é a chance de o banco de dados usado ter uma implementação defeituosa da verificação em comparação com a chance de seu aplicativo ter uma implementação defeituosa da verificação?

E qual você altera com mais frequência?

Aposto que o banco de dados está correto a qualquer momento .

Seus desenvolvedores não estão pensando em distribuir o suficiente.

Reduza o ida e volta da rede para o aplicativo quando inserir / atualizar dados, pois o aplicativo precisa fazer mais consultas para verificar a integridade dos dados.

Bandeira vermelha ! 1 1

Se você está pensando:

  • verifique se o registro existe
  • caso contrário, insira o registro

você falhou no problema de concorrência mais básico: outro processo / thread pode estar adicionando o registro à medida que avança.

Se você está pensando:

  • verifique se o registro existe
  • caso contrário, insira o registro
  • verifique se o registro foi inserido como duplicado

você falhou em dar conta do MVCC: a visualização do banco de dados que você possui é uma captura instantânea no momento em que sua transação foi iniciada; ele não mostrar todas as atualizações que estão ocorrendo, e talvez nem mesmo cometeu.

Manter restrições em várias sessões é um problema muito difícil, seja feliz por ter sido resolvido no seu banco de dados.

1 A menos que seu banco de dados implemente corretamente a propriedade Serializable; mas poucos realmente o fazem.


Último:

E eu acho que, lidar com a integridade dos dados no aplicativo deixará uma mensagem de erro mais detalhada do que usar o banco de dados. Por exemplo: quando você cria um servidor API. Se você definir relações no banco de dados e algo der errado (como a entidade referenciada não existe), você receberá uma exceção SQL com a mensagem

Não analise mensagens de erro , se você usar qualquer banco de dados de nível de produção, ele retornará erros estruturados. Você terá algum código de erro, pelo menos, para indicar o que está possivelmente errado e, com base nesse código, poderá criar uma mensagem de erro adequada.

Observe que na maioria das vezes o código é suficiente: se você tiver um código de erro informando que não existe uma chave estrangeira referenciada, é provável que esta tabela tenha apenas uma chave estrangeira, para que você saiba no código qual é o problema .

Além disso, e sejamos honestos aqui, na maioria das vezes você não manipulará erros tão graciosamente de qualquer maneira. Só porque existem muitos deles e você deixará de dar conta de todos eles ...

... que apenas se vincula ao ponto de correção acima. Cada vez que você vê um "500: Erro interno do servidor" porque uma restrição de banco de dados foi acionada e não foi tratada, significa que o banco de dados salvou você, pois você esqueceu de lidar com isso no código.

Matthieu M.
fonte
3
Haha, você escreveu isso enquanto eu escrevia meu comentário, enfatizando ironicamente o argumento que nós dois estamos fazendo. Concordo totalmente: você não pode nem fazer integridade ou restrições no código que não é DB. As transações não podem ver os resultados de outras pessoas até que sejam confirmadas (e mesmo assim talvez não). Você pode ter a ilusão de integridade, mas está sujeita a tempo ou problemas sérios de escalabilidade devido a bloqueios. Somente o banco de dados pode fazer isso corretamente.
LoztInSpace 26/10/16
8
Todos os bons pontos. Outra é que os relacionamentos em um banco de dados são auto-documentados. Se você já teve que fazer engenharia reversa de um banco de dados que tivesse seus relacionamentos definidos apenas no código que o consultava, odiaria qualquer um que o faça dessa maneira.
27416 Kat
11
@ Kat11: Isso é verdade. E a auto-descrição também tem a vantagem de que as ferramentas podem entender facilmente os dados e agir sobre eles, o que pode ser útil algumas vezes.
precisa
11
Seu argumento sobre o MVCC não é preciso nos bancos de dados que implementam o isolamento SERIALIZABLE corretamente (as versões modernas do PostgreSQL, por exemplo - embora muitos RDBMSs principais não o façam). Nesse banco de dados, mesmo a primeira abordagem ingênua funcionaria corretamente - se houver conflito de gravações, elas serão revertidas como uma falha de serialização.
James_pic
11
Nos bancos de dados que implementam SERIALIZABLE corretamente, se você realizar todas as transações confirmadas com êxito, haverá algumas ordens (que podem não ser iguais às ordens de relógio de parede), como se você as executasse em série (sem simultaneidade) nessa ordem, todos os resultados teriam sido exatamente os mesmos. É difícil acertar, e as especificações SQL são vagas o suficiente para que você possa se convencer de que não há problema em permitir distorção de gravação no nível SERIALIZABLE, muitos fornecedores de banco de dados tratam SERIALIZABLE como ISOLATION DE INSTANTÂNEO (estou olhando para você Oracle).
James_pic
118

O banco de dados não precisa verificar a integridade dos dados toda vez que o aplicativo modifica os dados.

Este é um ponto profundamente equivocado. Os bancos de dados foram criados precisamente para esse fim. Se você precisa de verificações de integridade de dados (e se acha que não precisa delas, provavelmente está enganado), deixar o banco de dados lidar com elas é quase certamente mais eficiente e menos propenso a erros do que fazê-lo na lógica do aplicativo.

Kilian Foth
fonte
5
@ dan1111 Eu não entendo o seu comentário ... você está dizendo: restrições simples são impostas pelo banco de dados, portanto não são um problema para o código do aplicativo, restrições mais complexas são muito difíceis de implementar, então desista delas? Ou você está dizendo que implementar restrições complexas usando gatilhos de banco de dados (e mecanismo semelhante) é muito complexo e, portanto, é melhor implementá-las no código do aplicativo?
Bakuriu 26/10/16
47
Você não pode nem fazer integridade ou restrições no código que não é DB. As transações não podem ver os resultados de outras pessoas até que sejam confirmadas (e mesmo assim talvez não). Você pode ter a ilusão de integridade, mas está sujeita a tempo ou problemas sérios de escalabilidade devido a bloqueios. Somente o banco de dados pode fazer isso corretamente.
LoztInSpace 26/10
17
Curiosamente, para acompanhar o comentário de @ LoztInSpace, certa vez trabalhei para uma empresa (terrível) em que uma dessas tabelas era configurada de tal maneira que, em vez de permitir que o banco de dados aumentasse automaticamente o ID, o aplicativo adotou o ID das últimas linhas, adicionou um a ele e usou isso como o novo ID. Infelizmente, cerca de uma vez por semana, foram inseridos IDs duplicados, interrompendo o aplicativo ..
Trotski94 26/10/16
9
@ dan1111 Você nunca escreve bugs no aplicativo, certo?
user253751
4
@DavidPacker Posso concordar, no entanto, depois de ter vários clientes acessando o banco de dados, você pode impor restrições no banco de dados. A menos que você comece a bloquear tabelas por atacado em vez de por linhas, com o desempenho atingido.
Iker
51

As restrições devem estar no seu banco de dados, pois (com a melhor vontade do mundo), seu aplicativo não será a única coisa a acessar esse banco de dados.

Em algum momento, pode haver uma correção com script no banco de dados ou você pode precisar migrar dados de uma tabela para outra na implantação.

Além disso, você pode obter outros requisitos, como "O grande cliente X realmente precisa desta planilha de dados do Excel importada para o banco de dados de aplicativos esta tarde", onde você não terá o luxo de adaptar o código do aplicativo para se adequar a um script SQL sujo. em tempo.

É aqui que a integridade no nível do banco de dados salva seu bacon.


Além disso, imagine o desenvolvedor que assume sua função nesta empresa depois que você sai e é encarregado de fazer alterações no banco de dados.

Ele vai te odiar se não houver restrições de FK no banco de dados para que ele possa dizer quais relacionamentos uma tabela tem antes de alterá-la? ( Pista, a resposta é sim )

Paddy
fonte
33
Oh irmão. Não sei dizer quantas vezes tive que explicar às pessoas que um banco de dados tem mais de um cliente! Mesmo que, no momento, exista apenas um cliente e apenas uma avenida para a entrada de dados no sistema, projetar seu aplicativo e esquema com base nessa suposição é a melhor maneira para o Future Yoshi odiar o Yoshi passado.
precisa
9
@nikonyrh Eu não faria isso. As restrições existem para que os aplicativos possam confiar em dados consistentes. Desabilitar o FK 'apenas para entrar' é loucura.
Paddy
5
Acordado. Além disso, mesmo que seu aplicativo seja o único cliente, você pode ter versões diferentes do aplicativo tentando impor restrições um pouco diferentes. Geralmente, ocorre hilaridade (bem, na verdade não. É mais como 'caos e frustração total' do que 'hilaridade').
Iker
5
Eu posso absolutamente atestar isso. No meu caso, eu estava preso no MyISAM, que na verdade não suporta chaves estrangeiras, então acabei com 250 GB de dados com integridade imposta pelo aplicativo. Quando começou a remover os dados para obter um tamanho mais gerenciável do backlog, e quando ficou claro que o aplicativo em si não seria capaz de lidar com isso, o caos se seguiu. Não sei por que estou usando o pretérito; isso ainda está acontecendo agora e o problema (dois anos depois) ainda precisa ser resolvido. * sniff *
Lightness Races com Monica
11
Eu diria que uma base de código decente deve facilitar a gravação de um script único usando a camada de persistência do aplicativo pelo menos tão rapidamente quanto a gravação de SQL bruto. 'Modificar o código do aplicativo' nunca deve ser necessário para scripts únicos.
Jonathan Cast
17

Você deve ter relações no banco de dados.

Como a outra resposta observa, o desempenho da verificação de restrições será muito melhor nesse banco de dados do que no aplicativo. As verificações de restrição de banco de dados são uma das coisas em que os bancos de dados são bons.

Se você precisar de flexibilidade adicional - por exemplo, suas referências cruzadas no banco de dados -, poderá remover as restrições deliberadamente e com consideração. Ter consistência em seu banco de dados significa que você tem a opção de modificar essas restrições e a certeza da integridade referencial.

Kirk Broadhurst
fonte
11
Verdadeiro. Eu deveria ter dito que o desempenho da verificação de restrições será melhor tratado no banco de dados do que no aplicativo.
precisa
13
  • Não vivemos mais em um mundo de back-end <-> um front-end.
  • A maioria das soluções envolve front-end da web, front-end para celular, front-end em lote e front-end para iPad, etc.
  • Os mecanismos de banco de dados já possuem milhares de linhas de código testadas otimizadas para reforçar a integridade referencial.

Você pode realmente escrever e testar o código de imposição de integridade referencial quando tiver um código de resolução de problemas no domínio para escrever?

Tulains Córdova
fonte
2
"Não vivemos mais em um mundo de back-end <-> um front-end." Nós já fizemos? Alguns anos atrás, trabalhei em um sistema de banco de dados que tinha programas escritos em pelo menos duas dúzias de idiomas diferentes acessando-o. Alguns dos programas tiveram seu primeiro lançamento na década de 1970.
Mike Sherrill 'Cat Recall'
2

Se você não validar a integridade dos dados, restrições, relacionamentos etc. no nível do banco de dados, isso significa que é muito mais fácil para qualquer pessoa com acesso ao banco de dados de produção (através de qualquer outro cliente, incluindo uma ferramenta de acesso ao banco de dados) atrapalhar seus dados.

É uma boa prática impor a mais estrita integridade de dados possível no nível do banco de dados. Confie em mim, isso poupará enormes dores de cabeça ao longo do tempo em qualquer sistema não trivial. Você também detectará erros de lógica de aplicativo ou erros de requisitos de negócios e inconsistências mais rapidamente se uma reflexão cuidadosa for colocada nisso.

Como observação lateral, projete seu banco de dados da maneira mais normalizada e atômica possível. Não há mesas de "Deus". Gaste muito esforço projetando seu banco de dados para ser o mais simples possível, idealmente com muitas tabelas pequenas que são individualmente muito bem definidas, com uma única responsabilidade e cuidadosamente validadas em todas as colunas. O banco de dados é o último guardião da sua integridade dos dados. Representa a Fortaleza do Castelo.

Brad Thomas
fonte
1

A maioria das pessoas está dizendo essencialmente "sim, em geral você sempre definirá as relações no banco de dados". Mas se as disciplinas em ciência da computação fossem tão fáceis, seríamos chamados de "Leitores de manuais de software" em vez de "Engenheiros de software". Na verdade, eu concordo que as restrições devem estar no banco de dados, a menos que haja um bom motivo para não fazê-lo, então deixe-me fornecer alguns motivos que podem ser considerados bons em determinadas situações:

Código duplicado

Às vezes, existe uma certa quantidade de funcionalidade que pode ser manipulada pelo banco de dados no código do aplicativo. Se adicionar algo como restrições ao banco de dados for redundante, é melhor não duplicar a funcionalidade, porque você está violando os princípios DRY e pode piorar o ato de malabarismo de manter o banco de dados e o código do aplicativo sincronizados.

Esforço

Se o seu banco de dados já estiver fazendo o que é necessário sem o uso de recursos avançados, convém avaliar onde seu tempo, dinheiro e esforço devem ser colocados. Se a adição de restrições impediria uma falha catastrófica e, assim, poupar muito dinheiro à sua empresa, provavelmente vale a pena. Se você estiver adicionando restrições que devem manter, mas já garantem que nunca serão violadas, você estará perdendo tempo e poluindo sua base de códigos. Garantido é a palavra operativa aqui.

Eficiência

Normalmente, esse não é um bom motivo, mas em alguns casos você pode ter um determinado requisito de desempenho. Se o código do aplicativo puder implementar uma certa funcionalidade de maneira mais rápida que o banco de dados, e você precisar de desempenho extra, poderá ser necessário implementar o recurso no código do aplicativo.

Ao controle

Um pouco relacionado à eficiência. Às vezes, você precisa de um controle extremamente refinado sobre como um recurso é implementado e, às vezes, fazer com que o banco de dados o manipule oculte-o atrás de uma caixa preta que você precisa abrir.

Pontos finais

  • Bancos de dados são escritos em código. Não há nada mágico que eles façam que você não possa fazer em seu próprio código.
  • Nada é gratuito. Restrições, relações, etc. todos usam ciclos de CPU.
  • As pessoas no mundo NoSQL se dão muito bem sem os recursos relacionais tradicionais. No MongoDB, por exemplo, a estrutura dos documentos JSON é boa o suficiente para suportar um banco de dados inteiro.
  • O uso cego e ignorante de recursos avançados de banco de dados não pode garantir nenhum benefício. Você pode acidentalmente fazer algo funcionar apenas para quebrá-lo mais tarde.
  • Você fez uma pergunta muito geral sem listar requisitos ou restrições específicas. A verdadeira resposta para sua pergunta é "depende".
  • Você não especificou se este era um problema de escala corporativa. Outras respostas estão falando sobre coisas como clientes e integridade de dados, mas às vezes essas coisas não são importantes.
  • Suponho que você esteja falando de um banco de dados SQL Relational tradicional.
  • Minha perspectiva vem do fato de ter deixado de usar toneladas de restrições e chaves estrangeiras em projetos pequenos (até 50 tabelas) e sem perceber nenhuma desvantagem .

A última coisa que direi é que você saberá se não deve colocar a funcionalidade no banco de dados. Se você não tiver certeza, provavelmente será melhor usar os recursos do banco de dados, porque eles geralmente funcionam muito bem.

parker.sikand
fonte
11
Se as pessoas rejeitarem respostas bem pensadas porque discordam de seus dogmas, o SE StackExchange se tornará um lugar pior.
22816 Carl Leth
5
A premissa desta resposta de que há ocasiões em que você pode deixar restrições fora do banco de dados é válida, mas a explicação é fraca e enganosa. Embora eu concorde que o banco de dados não é o melhor lugar para algumas restrições, nenhum banco de dados relacional deve ficar sem restrições básicas de chave e integridade referencial . Nenhuma . Não há nenhuma exceção a isso. Todo banco de dados precisará de chaves primárias e a grande maioria precisará de chaves estrangeiras. Esses sempre devem ser aplicados pelo banco de dados, mesmo que ele duplique a lógica. O fato de você encobrir isso é o motivo de eu ter votado mal.
jpmc26
11
"Os bancos de dados são escritos em código. Não há nada mágico que eles não possam fazer em seu próprio código." , não, você não pode impor a integridade referencial no código do aplicativo (e se você não precisa impor isso, por que está usando um servidor de banco de dados?). Não é sobre o que o código pode fazer, é sobre onde pode ser feito.
Hyde
0

Como sempre, há muitas respostas. Para mim, encontrei uma regra simples (bem, isso só funciona para uma abordagem centrada no modelo). Normalmente, concentro-me apenas nas diferentes camadas de aplicativos.

Se o modelo consistir em várias entidades e houver dependências entre as entidades, a camada de persistência deve refletir essas dependências com suas possibilidades. Portanto, se você estiver usando um RDBMS, também deverá usar chaves estrangeiras. A razão é simples. Dessa forma, os dados são sempre válidos na estrutura.

Qualquer instância que esteja trabalhando nessa camada de persistência pode confiar nela. Suponho que você esteja encapsulando essa camada via interface (serviço). Então aqui está o ponto em que o design termina e o mundo real começa.

Analisando seus pontos, especialmente as referências entre bancos de dados . Nesse caso, sim, não deve haver uma referência implementada no próprio RDBMS, mas no serviço. Mas antes de seguir esse caminho, não seria melhor considerar isso já durante o design?

Significa, se eu já sei, que existem partes que precisam ser armazenadas em um banco de dados diferente, então eu posso colocá-las e defini-las como modelo separado. Direito?

Você também está apontando que implementar isso no código é mais flexível . Certo, mas não parece que você está lidando com um design incompleto? Pergunte a si mesmo, por que você precisa de mais flexibilidade?

O problema de desempenho, devido às verificações de integridade no banco de dados, não é real. O RDBMS pode verificar essas coisas muito mais rapidamente do que qualquer implementação sua. Por quê? Bem, você tem que lidar com a interrupção da mídia, o RDBMS não. E pode otimizar essas verificações usando suas estatísticas também

Então você vê, tudo volta ao design. Claro que você pode dizer agora, mas e se um requisito desconhecido estiver aparecendo, um divisor de águas? Sim, pode acontecer, mas essas mudanças devem ser projetadas e planejadas também. ; o)

DHN
fonte
0

Você tem respostas muito boas, mas mais alguns pontos

Integridade de dados é o que um banco de dados foi projetado para fazer

Fazer simultaneidade adequada como uma exclusão de FK no nível do aplicativo seria horrível

A experiência em integridade de dados é com um DBA

Ao nível do programa de inserir, atualização, atualização em massa, inserção em massa, volume excluir ...
Thin client, cliente de espessura, cliente móvel ....
A integridade dos dados não é a experiência de um programador - lotes de código e alguém duplicado vai mexer isso

Digamos que você seja hackeado - você está com problemas de qualquer maneira, mas um hacker pode causar muitos danos através de um pequeno orifício se não houver proteção de integridade no banco de dados

Pode ser necessário manipular dados diretamente via SQL ou TSQL.
Ninguém lembrará de todas as regras de dados

paparazzo
fonte
0

Sua pergunta não faz sentido: se você pode alterar o banco de dados, é código, se não pode alterar o banco de dados, terá que criar suas restrições em outro lugar.

Um banco de dados que você pode alterar possui tanto código quanto qualquer linha de ruby, javascript, c # ou ada.

A questão sobre onde colocar uma restrição em seu sistema deve se resumir à confiabilidade, custo e facilidade de desenvolvimento.

jmoreno
fonte
0

Há toneladas de boas respostas aqui. Acrescentarei que, se você tiver um aplicativo escrito no idioma Y, poderá criar um código semelhante a uma restrição de banco de dados em Y. E então alguém quiser acessar seu banco de dados usando o idioma Z, precisará escrever o mesmo código novamente. Deus o ajude se as implementações não forem exatamente as mesmas. Ou quando um usuário comercial experiente se conecta ao seu banco de dados usando o Microsoft Access.

Minha experiência me diz que quando as pessoas não querem usar restrições de banco de dados, é porque estão realmente tentando fazer algo da maneira errada. Por exemplo, eles estão tentando carregar dados em massa e desejam deixar colunas não nulas por um tempo. Eles pretendem "consertar isso mais tarde" porque a situação que tornou crítica a restrição não nula "não pode acontecer neste caso". Outro exemplo pode ser quando eles estão tentando conectar dois tipos diferentes de dados na mesma tabela.

Pessoas mais experientes darão um passo atrás e encontrarão uma solução que não envolva a tentativa de contornar uma restrição. A solução poderia ser simplesmente a restrição não é mais adequada porque os negócios mudaram, é claro.

Tony Ennis
fonte