Restrições nos bancos de dados relacionais - Por que não removê-los completamente?

20

Existe algum motivo para criar restrições entre tabelas (dentro do SQLserver) hoje em dia? Se assim for, quando? A maioria dos aplicativos na minha área é baseada em princípios de objetos e as tabelas são unidas sob demanda. A demanda é baseada na necessidade do aplicativo. Não carregarei várias tabelas restritas para uma pesquisa simples, que por sua vez (após a ação) exige uma pesquisa simples outra.

Ferramentas ORM como EntityContext, Linq2Data e NHibernate também lidam com as restrições por si mesmas, pelo menos você sabe quais tabelas precisam uma da outra. Fazer restrições dentro do servidor é apenas fazer (forçar) as mesmas alterações duas vezes?

Isso geralmente não é uma questão de decisão, mas esse banco de dados foi projetado de maneira bem diferente. O design parece regular, espelhando principalmente os objetos usados ​​pelos aplicativos. O que me incomoda são todas as restrições configuradas dentro do SQLserver com "not cascade". O que significa que você precisa jogar "procurar e encontrar" ao codificar novas consultas ao banco de dados. Alguns casos requerem até 10 níveis de uma ordem exata para fazer uma única exclusão.

Isso me surpreende e não tenho certeza de como lidar com isso.

No meu mundo simples, esse cenário faz com que as restrições percam a maior parte do objetivo. OK se o banco de dados foi acessado a partir de hosts sem conhecimento do design.

Como você agiria nesse cenário?
Por que não remover todas as restrições do db e mantê-las no nível do aplicativo?

Independente
fonte
6
Você estava planejando sempre acessar os dados através de uma única ferramenta ORM? Ou você estava planejando se divertir replicando todas as restrições corretamente em cada ferramenta ORM em uso?
Donal Fellows
1
Pelo meu último comentário a Peter, eu tenho que concordar. O ponto de confiar todas as restrições à base de código (e removê-las do db) era muito restrito e provavelmente é totalmente aplicável a aplicativos de vida curta. Provavelmente também para alguns desenvolvedores / projetos da RAD.
Independente
4
Nitpick menor: acho que fica um pouco confuso quando você chama as conexões de chave estrangeira entre as tabelas "relações". As "relações" em um banco de dados relacional são as próprias tabelas, não as conexões. Especialmente quando falamos sobre "design relacional" - isso significa tabelas ou chaves estrangeiras?
Thomas Padron-McCarthy
Obrigado. Eu chamo as "conexões entre as tabelas" por restrições. Portanto, você provavelmente está certo de que vejo "banco de dados relacional" para os princípios do design de tabelas (estrutura de tabelas). Uma descrição ainda mais precisa seria "padrão de design", quando relacionado ao banco de dados "relação versus objeto".
Independente
1
Seu banco de dados sobreviverá ao código do aplicativo. Além disso, seu ORM está prejudicando o desempenho do aplicativo e há uma boa chance de você querer ignorá-lo, pelo menos em certos casos de uso. Se você não o conhece agora, saberá eventualmente. samsaffron.com/archive/2011/03/30/… . Além disso, a remoção de todas as restrições deixa seu banco de dados completamente incapaz de proteger sua própria integridade quando é abusado por aplicativos que não o seu, que podem ser de outro aplicativo real a um executivo no corredor com o Excel.
Craig

Respostas:

46

Duas razões gerais para não remover restrições do DB :

  • Pode ser acessado por mais aplicativos, agora ou no futuro , que podem ou não usar o ORM. Mesmo se os desenvolvedores desses aplicativos duplicarem fielmente todas as restrições existentes (o que pode ser significativamente mais difícil usando soluções não ORM de nível inferior), é sempre um trabalho extra. E se não, mesmo uma pequena omissão é suficiente para quebrar a integridade do esquema ... o que é algo que você não deseja arriscar. Na maioria das empresas, os dados armazenados no banco de dados são a força vital de seus negócios, portanto sua integridade deve ser garantida por qualquer meio. E o melhor meio testado e comprovado para conseguir isso é implementar o maior número possível de restrições no banco de dados.
  • O otimizador de consulta depende muito das restrições conhecidas no nível do banco de dados. Se você remover restrições, o desempenho da consulta poderá começar a se deteriorar . Você pode não perceber imediatamente, mas um dia isso o atingirá e, a essa altura, talvez seja tarde demais para corrigi-lo facilmente. A natureza das coisas é que o desempenho do banco de dados tende a se deteriorar no horário de pico, quando há a menor possibilidade de fazer melhorias de design cuidadosas e bem pensadas, apoiadas por medições exatas de desempenho e análises detalhadas para identificar as causas principais.

Seu caso concreto parece que o esquema do banco de dados pode ter sido originalmente gerado por uma ferramenta ORM (ou projetada por alguém não muito experiente no mundo relacional); portanto, é subótimo do ponto de vista relacional. Provavelmente, é melhor analisá-lo e aprimorá-lo para obter um design relacional mais "natural", mantendo-o consistente com as visualizações ORM. Pode ser útil envolver um especialista em DB nessa análise.

Péter Török
fonte
5
@ Jonas, então converse com o cara sobre os problemas percebidos com seu design de banco de dados. Relacional e orientado a objetos são dois mundos diferentes - nenhum é um "aprimoramento" sobre o outro em si, e ambos têm seu próprio lugar. Projetar um aplicativo C # com base em princípios relacionais é um erro tão grande quanto projetar um banco de dados da maneira OO.
Péter Török
3
@Jonas, refletindo as suas atualizações: se você precisar escrever consultas excessivamente complexas para conseguir coisas aparentemente simples no esquema do banco de dados, isso é um sinal de que o design do banco de dados é inadequado para o seu objetivo - ou que você não é suficientemente qualificado (por favor não se ofenda, não é óbvio a partir do seu posto como você é experiente com SQL como um aviso, eu mesmo estou longe de ser um especialista)..
Péter Török
1
Eu provavelmente tenho algumas expressões para aprender, para me tornar perceptível :). Reli a pergunta e as respostas e tenho que reverter. Definitivamente, um ponto forte é ter o DB como mestre para todas as restrições. Todos os sistemas precisam ser projetados a partir disso. Uma visão muito estreita para dizer que a base de código faria o trabalho. Se todo sistema puder ter sua própria decisão sobre restrições, isso terminará em um ponto alto com relações sugeridas erradas e tabelas inteiras órfãs. Caso contrário, ocorre mais tarde com outros codificadores.
Independente
8
"Pode ser acessado por mais aplicativos, agora ou no futuro." Para não mencionar alguns administrador de banco de dados, executar consultas SQL matérias para corrigir um problema com o banco de dados, enquanto os usuários estão esperando ...
Thomas Padron-McCarthy
5
+1: se db é armazenar dados de negócios (e não apenas aplicativo de configuração etc), então a probabilidade de que o banco de dados será transmitido ao vivo / ou ser estendida fora do aplicativo atual está se aproximando de 100%
Binary Worrier
27

Os aplicativos podem ir e vir, mas os dados são eternos. Na minha empresa, o DB tem mais de 30 a 40 anos e permanecerá enquanto a empresa existir. As aplicações mudam, os desenvolvedores vêm e vão. É melhor ter integridade e um bom modelo de dados lógicos. Dessa forma, alguém pode ver os dados e obter uma compreensão significativa sem ter que passar por uma complexa base de código. Isso também ajuda a relatar significativamente. Os aplicativos também podem e terão bugs, e a restrição de banco de dados é uma proteção contra isso. Minha posição padrão é ter o máximo de restrição possível (FK e cheque).
A única razão para não ter uma restrição seria se o seu padrão de design não permitir isso, por exemplo, Tabela por hierarquia ou problemas de desempenho.

softveda
fonte
Eu vou dizer, você está fazendo um conselho muito sábio aqui. Minha opinião pode corresponder melhor ao desenvolvimento do RAD ou ao desenvolvimento em que os aplicativos tenham uma vida útil curta - apenas por uma questão de manutenção minimizada durante o desenvolvimento.
Independente
15

O que me incomoda são todas as restrições configuradas dentro do SQLserver com "not cascade".

Isso não é perturbador para mim, significa que alguém demonstrou bom senso. As exclusões em cascata geralmente são muito ruins para o banco de dados. Em primeiro lugar, às vezes você deseja que uma exclusão falhe se você tiver dados em tabelas relacionadas. Por exemplo, se você tem um cliente com um pedido no passado, não deseja que ele seja excluído ou perde os dados sobre quem era o pedido e uma exclusão em cascata se livra do registro que prejudicaria os relatórios financeiros .

Você parece pensar que a facilidade de desenvolvimento é a coisa mais importante. No mundo dos bancos de dados, isso simplesmente não é verdade. A integridade dos dados é a primeira coisa mais crítica seguida de perto pelo desempenho e segurança dos dados. Se levar mais tempo para escrever as consultas, que assim seja.

O banco de dados geralmente é acionado por muitos aplicativos = um ou mais sites ou aplicativos de desktop, um aplicativo de relatório, serviços da web, janela de consulta, processos ETL etc. Se você não impõe restrições no nível do banco de dados, primeiro perde a integridade. dos dados como um desses aplicativos pode não seguir todas as regras. Segundo, você deve codificar essas restrições várias vezes e reescrevê-las se decidir usar um aplicativo diferente posteriormente. Terceiro, você não pode controlar antecipadamente se haverá a necessidade de executar algum tipo de tarefa de manutenção de dados que não ocorrerá através do aplicativo (corrigir os dados de uma importação incorreta de dados do cliente, por exemplo, ou alterar todos os 10.000.000 registros de um cliente para outro cliente quando a empresa é comprada por um concorrente). Normalmente, os desenvolvedores de aplicativos não

HLGEM
fonte
Obrigado pela resposta. Todos os processos e tipos de aplicativos de que você fala devem conversar com um DAL (que por sua vez conteria as restrições). MAS! Seu ponto de vista é perfeito e seu comentário é bom. Sidenote: Sim. Costumo tentar maneiras de facilitar o desenvolvimento. Para mim, menos complexidade pode representar menos maneiras de fazer errado. Isso não é "deseja desenvolver mais fácil / mais rápido", mesmo que possa ser - se for tratado de maneira errada. Por isso, porque estou postando esta pergunta! Eu também veria o bom senso de alguém se essa não cascata fosse escolhida com bom senso, não 100% como neste cenário. Eu tenho que descobrir razões.
Independente
@Jonas, pode haver razões de desempenho também. Depende do número de registros filho. OK, se você estiver excluindo pequenos grupos, mas se milhões de registros forem acionados, é melhor fazer lotes e não bloquear todas as tabelas enquanto todo o processo acontece. Em geral, muitos dbas não permitem exclusões em cascata apenas por esse motivo, pois podem bloquear um sistema prod se uma exclusão afetar muitos registros.
HLGEM
2
Nem todos os processos não devem conversar com um DAL. Os processos de ETL geralmente não acontecem nem acontecem no nível do banco de dados que afetam muitos registros quando ocorrem grandes alterações (como o cliente sendo comprado). Você também não pode proibir ninguém de usar a janela de consulta para fazer uma alteração única. Nunca vi um banco de dados que não aplicasse restrições no nível do banco de dados que não apresentavam problemas de integridade ao longo do tempo.
HLGEM
10

Li em algum lugar uma vez que dizia basicamente: Os dados são a chave do seu aplicativo . Se você NUNCA acessar dados através da sua interface do usuário (e eu quero dizer sempre , como agora e para sempre, por toda a eternidade ... ou durante toda a vida útil do seu aplicativo), não será necessário restringir o banco de dados. Mas sempre existe a chance de que algo que não seja o aplicativo em si precise tocar em dados, por exemplo, um serviço da Web, API pública, tarefa de rake / tarefa SQL / cron / cron / script automatizado, para evitar muitos problemas em potencial. estrada, mantendo as restrições do banco de dados.

Acredito firmemente que essa é a única área de desenvolvimento de software em que você não deve aplicar o DRY (e estou esperando um grande número de votos negativos para essa afirmação). Seus dados são o coração e a alma do seu aplicativo - se ele estiver corrompido além do reparo, é isso: game over. Vale a pena IMO impor as restrições em todos os lugares que são necessários. Se isso significa na forma de gatilhos e restrições no nível do banco de dados, validações do lado do servidor no middleware e Javascript do lado do cliente na interface do usuário (para aplicativos da web), então é IMO um mal necessário para garantir que os dados estejam sempre intactos .

Wayne Molina
fonte
6

Você sabe o que significa ORM? Mapeamento objeto-relacional. Citando a Wikipedia "técnica para converter dados entre sistemas de tipos incompatíveis ". Sim, modelos relacionais e de objetos não se encaixam. ORMs fazem uma conversão muito boa, respeitando as regras dos dois tipos de sistemas. Os RDBMS são organizados de maneira que você atinja a integridade dos dados usando restrições. Em geral, a integridade é algo muito bom de se ter, portanto os ORMs costumam usá-los ao criar um modelo de dados para armazenar dados do objeto. Seu ORM provavelmente tem um bom motivo para usar restrições "não em cascata". E se isso forçar você a fazer consultas complicadas em vez de apenas criar / atualizar / soltar determinados objetos, algo está errado com sua configuração do ORM.

Se você considera o conceito relacional irritante, por que não usa o banco de dados de objetos? Algum tempo atrás, eles eram lentos (e é por isso que a maioria das pessoas ainda usa RDBMSs), mas pelo que ouvi, as coisas mudaram um pouco. Você se livraria de todos os truques relacionais. Simplesmente objetos dentro, objetos fora.

Jacek Prucia
fonte
O tópico trata de mudar a funcionalidade de restrição do DB e confiar nas configurações / desenvolvimento dentro da base de código (por exemplo, net falando: Entity / Linq2Sql).
Independente
Sim, eu sei, mas meu argumento é que você precisa primeiro entender por que existem restrições em primeiro lugar e, em seguida, por que pode ser uma má idéia eliminá-las.
Jacek Prucia
Se mudou! Não caiu. Entendo que você se arrepende do conhecimento da questão, da qual não se tratava.
Independente
Você não pode realmente mover nada entre sistemas incompatíveis. Você vai eliminar as restrições de banco de dados, introduzir restrições de aplicativos e apenas esperar que elas funcionem da mesma forma (o que pode ser verdadeiro e falso). De qualquer forma, meu sincero pedido de desculpas se eu entendi mal sua pergunta.
Jacek Prucia
Obrigado! "Mover" significa "movimento" literário. O que significa que você cria (boa expressão) restrições de aplicativos em todos os sistemas. Pelo menos cada sistema que não pode compartilhar o mesmo DAL. Um exemplo muito bom foram as consultas diretas de um administrador de banco de dados que "corrigem algo". Nenhuma restrição de banco de dados e falta de conhecimento de design podem resultar em dados órfãos ou em dados completamente simulados.
Independente
6

Bem, foi isso que o eBay fez e eles provavelmente têm um dos maiores bancos de dados do mundo:

http://www.dba-oracle.com/oracle_news/news_ebay_massive_oracle.htm http://www.addsimplicity.com/downloads/eBaySDForum2006-11-29.pdf

Apesar do que foi dito acima sobre o desempenho ser aumentado pela integridade referencial, ele pode realmente ser degradado; é por isso que bancos de dados maciços eliminam suas restrições e fazem o trabalho na camada de aplicativos. E, tanto quanto posso dizer, é a única razão realmente boa.

Ao eliminar essas restrições, você essencialmente perde sua rede de segurança que mantém os dados limpos e gera seus próprios problemas. Assim como em tudo, é um ato de equilíbrio. Eu acho que, em geral, manter a integridade referencial é a coisa certa a se fazer.

Tendo trabalhado em um ambiente de desenvolvimento com forte integridade referencial, sei que, do ponto de vista de um desenvolvedor, pode ser uma dor total; geralmente em um ambiente de desenvolvimento, um pouco de dados sujos não importa e descobrir como excluir uma linha pode levar uma hora ou mais. No entanto, também pode ser muito útil, pois as restrições tornam o esquema explícito.


fonte
Finalmente alguém que me entende :-). Você está completamente certo, o equilíbrio é realmente um ponto importante aqui. Mover restrições para o nível do aplicativo pode ser uma alternativa segura, se feito como um ponto estratégico. Seria bom com alguns URLs para sites com desempenho degradado comprovado devido a fortes restrições / integridade.
Independente
10
Sim e não esqueça - não se esqueça - de que o Ebay, como o Facebook e a Amazon, é um zilhão de vezes maior que 99,99% dos bancos de dados, e o que é bom para eles é provavelmente muito diferente do que é bom para o seu banco de dados.
Tony Andrews
2
E ebay, Facebook, Amazon provavelmente não usam bancos de dados sem restrições para seu software financeiro e contábil, seu software de inventário ou seus dados de RH ou qualquer outro lugar onde a perda de dados não seja crítica.
HLGEM
2
Se você tiver tempo, experiência e dinheiro suficientes, poderá eventualmente programar qualquer RDBMS, servidor da web ou sistema operacional para atender a uma necessidade específica.
JeffO 13/05
1
O eBay não fez isso até que o grande volume de rotatividade de dados com os quais eles estavam lidando ultrapassou essencialmente a capacidade dos servidores de banco de dados de lidar e eles tinham milhões para investir em sua nova arquitetura. Se você está fazendo bilhões de transações por dia, então se preocupe em remover restrições e acessar um sistema totalmente escalável, baseado em filas, sem transações e escalonável como o eBay. Caso contrário, não subestime o servidor de banco de dados e não o deixe sujeito a corrupção de dados removendo todas as suas restrições.
Craig
4

Primeiro - minha resposta: não, você não deve confiar apenas no aplicativo para cuidar dos seus dados.

Isso aponta para um debate maior: as ORMs incentivaram uma cultura de desdém pela interação "direta" com o banco de dados, geralmente à custa da normalização / integridade referencial. As tabelas são mapeadas à força para hierarquias arbitrárias de objetos, à custa do design implícito no modelo relacional. O desacoplamento favorecido pelo OOP é sem dúvida sacrificado aqui, pois o aplicativo faz com que seu design seja sentido na estrutura de dados. Embora o ORM tenha demonstrado grande utilidade, parece basear-se no abuso ou desconfiança do SQL.

Novos paradigmas estão (re) emergindo, como a programação funcional, por exemplo. Se a equipe de desenvolvimento decidir adotar uma nova metodologia de programação, que implicações isso terá para os dados que foram estruturados de acordo com os requisitos do ORM?

Concordo com @Jacek Prucia - acho que o ORM é uma má combinação para o RDBMS, eu pessoalmente optaria por um DBAL no RDBMS ou optaria por um OODB com o ORM.

sunwukung
fonte
+1 para falar alternativas ao tópico. O outro lado do debate é claro: "Quão ruins seriam alguns dados?" e a resposta pode ser o cancelamento ou a inserção de bilhões de dólares em contas bancárias de milhões de dólares. Bem como alguns dados órfãos que são removidos com boas rotinas de limpeza. O resumo deste tópico parece consistência com o custo da flexibilidade. O que, por sua vez, depende totalmente da gravidade do conteúdo e do uso do banco de dados.
Independente
3

As restrições são sua única garantia de que você tenha consistência e integridade de dados no nível do banco de dados. Claro, você pode impor restrições usando o código do aplicativo, mas e se, no futuro, você precisar modificar os dados diretamente? Você pode entender como manter a integridade dos dados, mas outra pessoa talvez não. Manter as restrições no nível dos dados garante que a integridade seja garantida, mesmo quando alguém estiver pesquisando em lugares que não entende.

Além disso, digamos que seu aplicativo precise ser reescrito, mas com o mesmo banco de dados. Todas essas restrições no código estão apenas implorando por erros que impedem alguma entrada, permitindo a passagem de dados errados.

Ao desenvolver, mantenha-o simples. As restrições permitem que você faça isso. (Dito isto, quando uma restrição gerar um erro, não cuspa o mesmo erro de volta ao usuário. Torne o erro compreensível.)

(Quanto à questão da cascata: isso é bom. Prefiro lançar um erro de que certos outros registros precisam ser excluídos primeiro, em vez de confiar na cascata para fazer tudo certo. As cascatas são boas em teoria, mas não necessariamente na prática.)

Kerri Shotts
fonte
2

Um problema com restrições em um banco de dados é que eles fornecem ao programa informações limitadas sobre o que falhou e como corrigi-lo. Isso significa que, para um manuseio suave, geralmente é necessário repetir a verificação de restrição no aplicativo e, portanto, a verificação de restrição do banco de dados é um esforço desperdiçado.

Isso corre o risco de comprometer a integridade dos dados, por isso temos vantagens e desvantagens aqui. Para dados importantes, garantir a integridade dos dados é quase sempre mais importante que o desempenho, e é muito melhor falhar em uma transação, mesmo que pareça arbitrário do que atrapalhar os dados.

Para remover restrições com segurança, é vital proteger o acesso ao banco de dados para que nada possa mudar o banco de dados sem verificar as restrições. Isso não é confiável ao escrever novos aplicativos ou criar maneiras ad hoc de lidar com os dados, pois basta um erro e o banco de dados está corrompido.

Portanto, para dispensar as restrições do banco de dados, é necessário estabelecer o que pode e o que não pode ser feito com o banco de dados antecipadamente, para que todos os aplicativos possam ser gravados, revisados ​​e testados extensivamente. Todos os requisitos do banco de dados devem ser estabelecidos com antecedência, e qualquer alteração nos requisitos do banco de dados exigirá um trabalho extenso. Isso é uma metodologia de cascata congelada, que funciona apenas em casos muito específicos. (Projetar, implementar e manter os requisitos é como andar na água. Algo deve ser congelado primeiro e, se não estiver congelado o suficiente, os resultados podem ser desastrosos.)

Um caso em que funciona são os aplicativos corporativos maciços como PeopleSoft e SAP, onde o aplicativo já faz praticamente tudo e existem maneiras cuidadosamente definidas de estendê-lo. Existem outras possibilidades, muito raras.

Portanto, a menos que você trabalhe em um projeto corporativo muito grande (e eu não gostaria) ou possa andar com água líquida, deixe essas restrições no banco de dados.

David Thornley
fonte
1
Obrigado pela resposta. As restrições estarão no banco de dados para este projeto! Estou completamente convencido :). Também terei olhos mais abertos quando decidir isso em projetos futuros e em discussões com outras partes.
Independente
1
Considere também que, sem as restrições, você está deixando o código do aplicativo em si para detectar que ele estragou tudo. Esse é o mesmo código de aplicativo que violou a restrição em seu exemplo, a propósito, a restrição que salvou seu banco de dados de inconsistência ou corrupção de dados. O uso de restrições também não significa automaticamente desempenho inferior, a propósito, e a não utilização de restrições deixa o banco de dados exposto, de modo que não pode se proteger.
Craig