“Nunca faça em código o que você pode fazer com que o servidor SQL faça bem por você” - isso é uma receita para um design ruim?

204

É uma ideia que ouvi repetida em vários lugares. Um pouco mais ou menos reconhecendo que, uma vez que a tentativa de resolver um problema puramente no SQL excede um certo nível de complexidade, você deve realmente lidar com isso no código.

A lógica por trás da ideia é que, para a grande maioria dos casos, o mecanismo de banco de dados fará um trabalho melhor ao encontrar a maneira mais eficiente de concluir sua tarefa do que você poderia no código. Especialmente quando se trata de condicionar os resultados às operações executadas nos dados. Indiscutivelmente, com os mecanismos modernos, JIT'ing + efetivamente armazenando em cache a versão compilada da sua consulta, faria sentido na superfície.

A questão é se aproveitar ou não o mecanismo de banco de dados dessa maneira é uma prática inerentemente ruim de design (e por que). As linhas ficam borradas ainda mais quando toda a lógica existe dentro do banco de dados e você a está pressionando através de um ORM.

PhonicUK
fonte
60
Este é um daqueles ditados que devem ser tomados com consideração. Ele é ativado sempre que alguém encontra outro engenheiro fazendo 'select * from table' e, em seguida, vasculhando o conjunto de resultados em vez de usar uma cláusula where e especificar colunas. Mas se você for longe demais, você acaba com uma bagunça diferente.
22412 Michael Kohne
154
Iniciar uma frase com "nunca" ou "sempre" é quase sempre uma receita para um design ruim.
vsz 23/10/12
34
Embora seja certamente possível tentar fazer muita coisa em SQL, posso dizer honestamente que em 30 anos de desenvolvimento e consultoria, nunca vi um caso sério disso (alguns pequenos). Por outro lado, eu tenho visto literalmente centenas de casos graves de desenvolvedores tentando fazer muito em "código" que deveriam estar fazendo no SQL. E eu ainda os vejo. Frequentemente ...
RBarryYoung
2
@MrEdmundo Leve-o para meta.
ta.speot.is
4
Esta pergunta é duas em uma - acho que deveria ser dividida. 1) Quanto deve ser feito no SQL? 2) Quanto deve ser feito no DBMS? Os procedimentos armazenados ficam no meio. Eu vi aplicativos inteiros codificados em procedimentos armazenados.
Reinierpost

Respostas:

321

Nas palavras do leigo:

Estas são as coisas que o SQL é feito para fazer e, acredite ou não, eu já vi feito no código:

  • junta - codificaria exigir manipulação complexa de array
  • filtragem de dados (onde) - da mesma forma que seria necessário inserir e excluir muito itens nas listas
  • seleção de colunas - do mesmo modo, exigiria uma lista pesada ou manipulação de array
  • funções agregadas - da mesma forma que exigiria matrizes para manter valores e casos de comutação complexos
  • integridade de chave estrangeira - codificaria a necessidade de consultas antes da inserção e presume que ninguém usará os dados fora do aplicativo
  • integridade da chave primária - do mesmo modo que exigiria consultas antes da inserção e assume que ninguém usará os dados fora do aplicativo

Fazer essas coisas em vez de confiar no SQL ou no RDBMS leva à gravação de toneladas de código sem valor agregado , o que significa mais código para depuração e manutenção. E assume perigosamente que o banco de dados será acessado apenas através do aplicativo.

user61852
fonte
88
+10000000000 por apontar que assume perigosamente que tudo só acontecerá através do aplicativo.
HLGEM 23/10/12
11
@skynorth Isso leva ao design incorreto do banco de dados. Abaixo da linha, você acaba com um banco de dados que só pode ser acessado de forma significativa por esse aplicativo devido a todo o pós-processamento que ele faz.
Sirex
21
@skynorth Se você confiar no código para garantir que suas chaves mantenham a integridade, estará removendo um princípio fundamental do RDBMS do banco de dados. Isso não faz sentido, porque todos os aplicativos que acessam o banco de dados precisarão replicar com precisão essa funcionalidade. Por que não deixar o banco de dados lidar com isso, pois é para isso que ele foi projetado. O banco de dados pode impedir chaves duplicadas nativamente, por exemplo.
Buttle Butkus
10
não se esqueça de transações!
21312 Sklivvz
24
@skynorth: tl; dr: As regras que mantêm seus dados consistentes devem ser implementadas no banco de dados. isto é, para 99% dos aplicativos já gravados, os dados (e, portanto, o banco de dados) perdem muito tempo depois que seu aplicativo está inoperante. Eu já vi isso muitas e muitas vezes ao longo dos anos (ei, precisamos implantar uma versão no Windows / iPhone / Android / qualquer coisa nova, porque {insert old platform here} está morrendo, nós ' vai hospedar ou banco de dados Oracle aqui e criar uma nova UI ). Não há razão para esta tendência parar hoje ou em breve.
Worrier binário 24/10/12
122

Eu reformularia isso para "Nunca faça no código o que o SQL Server pode fazer por você também ".

Coisas como manipulação de strings, regex funcionam e outras coisas que eu não faria no SQL Server (exceto SQL CLR).

O acima tende a falar sobre coisas como - junções, operações definidas e consultas. A intenção por trás disso é delegar grande parte do trabalho pesado ao SQL Server (nas coisas em que é bom) e reduzir a quantidade de E / S o máximo possível (portanto, deixe o SQL fazer as junções e filtrar com uma WHEREcláusula, retornando muito conjunto de dados menor que o contrário).

Oded
fonte
27
Se tudo o que o SQL faria melhor do que o código do aplicativo fosse colocado na camada SQL, há muita lógica de negócios que acabaria no banco de dados, para melhor ou para pior. Eu já vi isso e sim, o desempenho foi estelar. Felizmente, porém, a equipe de desenvolvedores conhecia o desenvolvimento de aplicativos e o SQL extremamente bem, porque a fronteira entre os dois se tornou muito amorfa. Eu não sugeriria isso como um ponto de partida, mas um ponto final depois que o sistema se torna enormemente popular e o desempenho diminui com o tempo.
Jimmy Hoffa
3
Cavalos para cursos innit guv?
StuperUser
28
@ NathanLong Eu não sei por que tantas pessoas ainda pensam que você não pode manter seu SQL no controle de origem. No início, tínhamos todos os nossos procedimentos armazenados / scripts de tabela / etc necessários para criar o banco de dados do zero no controle de origem e, posteriormente, usamos projetos de banco de dados do visual studio. Funcionou bem sem os projetos e melhor com eles. O SQL, assim como todas as outras variáveis ​​necessárias para criar seu sistema, deve estar sob controle de versão! A implantação pode ser feita com ferramentas redgate diff para a maioria dos RDBMS se você manter seus criar scripts sob controle de versão, não manter scripts de diff usar ferramentas
Jimmy Hoffa
3
Se o seu SQL tiver suporte para operações REGEX e manipulação de cadeias, fazê-las no SQL pode ser uma boa opção.
Kevin cline #
3
@ NathanLong: pense assim, uma tabela de banco de dados é definida por um pedaço de código escrito em um arquivo de texto, a sintaxe é semelhante à "criar tabela ...". Agora você pode armazenar esse arquivo de texto no SCM que desejar, como se tivesse o código de criação de tabela do banco de dados em seu idioma favorito do aplicativo que chama a API necessária e armazenaria esse arquivo de texto no seu SCM. Eu acho que o problema é que algumas pessoas pensam que os DBs são de alguma forma bestas mágicas, e só sabem escrever código VB (ou o que seja) e, portanto, pensam apenas em termos da linguagem de aplicativo que conhecem.
Gbjbaanb
47

Nunca faça em código o que você pode fazer com que o servidor SQL faça bem por você (a ênfase é minha)

A chave da resposta é que você precisa procurar o SQL fazendo algo bem, em vez de simplesmente fazer algo por você. SQL é uma linguagem incrivelmente poderosa. Juntamente com as funções integradas, ele pode fazer muitas coisas. No entanto, o fato de você poder fazer algo no SQL não deve ser uma desculpa para realmente fazer isso no SQL.

Meu critério específico para tomar uma decisão é analisar a quantidade de dados que você recebe e o número de viagens de ida e volta: se você pode reduzir a quantidade de dados enviando uma tarefa ao servidor, sem aumentar o número de viagens de ida e volta viagens, a tarefa pertence ao servidor; se a quantidade de dados permanecer a mesma ou aumentar sem uma queda simultânea no número de viagens de ida e volta, a tarefa pertence ao seu código.

Considere estes exemplos:

  • Você armazena uma data de nascimento e precisa calcular a idade de um grupo de usuários. Você pode fazer com que o SQL Server faça a subtração ou em seu código. O número de viagens de ida e volta permanece o mesmo e a quantidade de dados enviados para você aumenta. Portanto, uma solução baseada em código ganha
  • Você armazena uma data de nascimento e precisa encontrar usuários com idades entre 20 e 30. Você pode carregar todos os usuários novamente no cliente, fazer a subtração para encontrar a idade e, em seguida, fazer a filtragem, mas enviando a lógica para o SQL Server reduziria a quantidade de dados sem exigir viagens adicionais; portanto, a solução baseada em SQL vence.
dasblinkenlight
fonte
1
Quando trabalhei em algum lugar, a lógica de negócios se tornou amorfa com o SQL, não tivemos problemas com várias viagens de ida e volta; nós apenas utilizados vários conjuntos de resultados em uma única ida e volta, de modo que regra quebra um bocado lá, embora o espírito da regra é muito bom em apontar para a média de ouro
Jimmy Hoffa
2
Marcar com +1 é uma resposta fantástica, pois fornece exemplos concretos para apoiar as duas direções.
Brandon
1
No seu segundo exemplo. o que você diz, se o cenário for o seguinte: os usuários e o bday são caches e dizem que o tamanho do registro está no intervalo de 1000 a 2000. Não é mais rápido fazer isso na memória? Não é necessária nenhuma chamada db, pois os dados são armazenados em cache e, portanto, a operação sql 'entre' é evitada. O processamento irá percorrer uma lista de mais de 1000 usuários na memória e descobrir onde a correspondência ocorre. Isso não vai ser mais rápido do que a fazê-lo em db
user4677228
1
@ user4677228 Mas tente ampliar :-p. Se o seu código precisar varrer todos os dados para calcular todas as idades e o resultado desejado for apenas "quantos usuários têm pelo menos 20 anos e menos de 30 anos?", Os caches não ajudarão em nada. Você ainda acabará transmitindo a tabela inteira para o seu cliente, mas o servidor de banco de dados poderá fazer isso tudo em sua memória / caches e fornecer uma resposta rápida, independentemente de o cliente db estar se conectando por soquetes locais ou remotamente pela rede, se você está apenas disposto a calcular a idade em uma WHEREcláusula.
binki
21

Em resumo , seria correto dizer que: "Nunca execute operações específicas do banco de dados em sua base de código", pois elas são melhor tratadas em seu banco de dados.

Veja o exemplo das operações de base definidas . Como você deve saber, o RDBMS é construído para lidar com operações comuns de armazenamento e manipulação de dados.

Além disso, a escolha do projeto do banco de dados desempenha um papel importante . Ter um RDBMS (MS SQL, Oracle, etc.) é diferente dos bancos de dados NoSQL como o RavenDB.

ElYusubov
fonte
Nunca colocar operações definidas em sua base de código significaria absolutamente tudo o que é feito no LINQ para coleções (select, sum, where, single) deve ser feito no SQL e não no seu aplicativo, isso colocaria MUITO lógica de negócios no banco de dados.
Jimmy Hoffa
4
As coisas que você descreve não são um código de cliente. É uma camada de negócios, onde você pode ter sua própria lógica de manipulação. No entanto, a execução dessa lógica em mais de 1 milhão de registros vai impactar você.
EL Yusubov 23/10/12
@ JimmyHoffa: Isso não é verdade, às vezes você gera informações transitórias que precisam ser processadas com os dados que você já possui na memória do aplicativo. Linq faz maravilhas nisso.
Fabricio Araujo
@FabricioAraujo Estou ciente de por que o linq é ótimo, mas esta resposta declara Nunca executar operações baseadas em código no aplicativo, se você nunca definiu operações no código do aplicativo, nunca usaria o linq porque esse é o objetivo do linq. Eu estou fazendo o ponto que nunca fazer operações definidas no código do aplicativo é uma regra ruim para seguir
Jimmy Hoffa
@ JimmyHoffa: Não, a regra diz "nunca faça no aplicativo o que o RDBMS pode fazer bem por você". E eu estou falando sobre informações transitórias - não persistiram informações no banco de dados. Trabalhei em sistemas nos quais, para cumprir as regras de negócios, precisava processar o código. Lembro-me de uma regra comercial que, depois de realizar um processamento pesado no DB, fazia um processamento adicional nesses dados para gerar um relatório (muito importante). Eu que eu poderia usar o linq nisso (foi feito no agora extinto Delphi.Net). Em outras palavras, o linq pode ser usado mesmo seguindo essa regra.
Fabricio Araujo
13

Como regra, seu banco de dados tem mais informações para trabalhar do que seu aplicativo e pode executar operações comuns de dados com mais eficiência. Seu banco de dados mantém índices, por exemplo, enquanto seu aplicativo precisaria indexar os resultados da pesquisa rapidamente. Sendo tudo igual, sua carga de trabalho geral pode ser reduzida empurrando o trabalho para o banco de dados e não para o aplicativo.

Mas, à medida que o produto é dimensionado, geralmente fica mais fácil dimensionar seu aplicativo do que escalar seu banco de dados. Em instalações grandes, não é incomum ver servidores de aplicativos superando em número os servidores de banco de dados por um fator de 10 para 1 ou mais. A adição de mais servidores de aplicativos geralmente é uma simples questão de clonar um servidor existente no novo hardware. Adicionar novos servidores de banco de dados, por outro lado, é muito mais difícil na maioria dos casos.

Portanto, neste ponto, o mantra torna-se proteger o banco de dados . Acontece que, ao armazenar em cache os resultados do banco de dados memcachedou enfileirar atualizações em um log do lado do aplicativo, ou buscando os dados uma vez e calculando suas estatísticas no aplicativo, você pode reduzir drasticamente a carga de trabalho do banco de dados, evitando que seja necessário recorrer a uma configuração de cluster de banco de dados ainda mais complicada e frágil.

tylerl
fonte
1
O dinheiro pode resolver problemas de escalabilidade de hardware, enquanto nenhuma quantidade de dinheiro pode resolver a complexidade do software.
Tulains Córdova
3
@ user1598390 De fato: o hardware é barato, os programadores são caros . O dinheiro pode resolver a complexidade do software. Dinheiro gasto em programadores. Mas observe que não estamos falando de código limpo versus speghetti. Estamos falando de realizar trabalhos no lado do aplicativo e no lado do banco de dados. A complexidade do software é apenas marginalmente relacionada, pois ambas as opções podem seguir bons princípios de design. Uma pergunta melhor é: " qual design custa mais? ".
tylerl
Depois que você tem uma base de código imensa e cheia de gordura, a maioria fazendo coisas não comerciais, a única coisa que você pode fazer é a mãe de todas as reengenharia, que custa mais que hardware e envolve muita incerteza, além de você sempre saberá onde encontrar um bom hardware, mas bons programadores são uma história diferente ... enquanto isso, seus concorrentes estão usando seu tempo para melhorar, adaptar-se às mudanças e fazer os clientes felizes.
Tulains Córdova
1
+1 por ser a única pessoa a mencionar escala na sua resposta.
23412 Matt
O hardware ficou barato, não é mais - no datacenter, a eletricidade e o hardware representam 88% do custo de operação (citado pela Microsoft), portanto, gastar mais com programadores para escrever código eficiente é muito econômico e durará até chegarmos ao limite e poder de fusão barato.
Gbjbaanb
12

Eu acho que seria um projeto ruim não usar o banco de dados para as coisas a que ele se destina. Eu nunca vi nenhum banco de dados em que as regras foram aplicadas fora do banco de dados com bons dados. E eu olhei para centenas de bancos de dados.

Então, coisas que devem ser feitas em um banco de dados:

  • Auditoria (a auditoria somente do aplicativo não rastreará todas as alterações no banco de dados e, portanto, é inútil).

  • A ingerência de dados restringe, incluindo valores padrão, restrições de chave estrangeira e regras que sempre devem ser aplicadas a todos os dados. Nem sempre todos os dados são alterados ou inseridos por meio de um aplicativo. Existem correções únicas, especialmente para grandes conjuntos de dados que não são práticos para executar um registro por vez (atualize esses 100.000 registros que foram identificados incorretamente como status 1 quando deveriam seja 2 devido a um erro no código do aplicativo ou atualize todos os registros do cliente A para o cliente B porque a empresa B comprou a empresa A) e as importações de dados e outros aplicativos que podem tocar o mesmo banco de dados.

  • JOINS e filtragem de cláusula where (para reduzir o número de registros enviados pela rede)

HLGEM
fonte
6

"A otimização prematura é a raiz de todo mal (a maioria, de qualquer maneira) na programação de computadores" - Donald Knuth

O banco de dados é exatamente isso; a camada de dados do seu aplicativo. Seu trabalho é fornecer ao aplicativo os dados solicitados e armazenar os dados fornecidos a ele. Seu aplicativo é o local para colocar o código que realmente funciona com os dados; exibindo, validando etc.

Embora o sentimento na linha de título seja admirável e preciso até certo ponto (o âmago da questão de filtragem, projeto, agrupamento etc. deve, no grande número de casos, ser deixado para o DB), uma definição de "bem" pode estar em ordem. As tarefas que o SQL Server pode executar com um alto nível de desempenho são muitas, mas as tarefas que você pode demonstrarque o SQL Server faz corretamente de maneira isolada e repetível são muito poucos. O SQL Management Studio é um ótimo IDE de banco de dados (especialmente considerando as outras opções com as quais trabalhei como o TOAD), mas tem suas limitações, a primeira delas é que praticamente qualquer coisa que você usa para fazer (ou qualquer código de procedimento que você executa) o banco de dados abaixo) é, por definição, um "efeito colateral" (alterar o estado fora do domínio do espaço de memória do processo). Além disso, o código de procedimento no SQL Server é agora, com os IDEs e ferramentas mais recentes, capazes de ser medidos da maneira que o código gerenciado pode usar métricas de cobertura e análise de caminho (para que você possa demonstrar que essa instrução if específica é encontrada pelos testes X , Y e Z, e o teste X foi projetado para tornar a condição verdadeira e executar essa metade enquanto Y e Z executam o "else" . Isso, por sua vez, pressupõe que você tenha um teste que pode configurar o banco de dados com um estado inicial específico, executar o código procedural do banco de dados através de alguma ação e afirmar os resultados esperados.

Tudo isso é muito mais difícil e envolvido do que a solução fornecida pela maioria das camadas de acesso a dados; suponha que a camada de dados (e, nesse caso, o DAL) saiba como executar seu trabalho quando receber a entrada correta e, em seguida, teste se o seu código fornece a entrada correta. Mantendo códigos procedimentais como SPs e gatilhos fora do banco de dados e, em vez disso, fazendo esses tipos de coisas no código do aplicativo, o código do aplicativo é muito mais fácil de exercitar.

KeithS
fonte
Espera, espera o que? Como você passou de provas de correção para testes, o que pode provar que existem erros, mas nunca pode provar que o código está correto?
Mason Wheeler
2
um procedimento armazenado não é um código de procedimento. Um SP é uma consulta SQL pré-calculada armazenada e executada dentro do banco de dados. Não é um código de aplicativo.
Gbjbaanb
1
Se o SP estiver limitado a uma consulta SQL, você estará certo. Se for T-SQL ou PL / SQL, incluindo quebras condicionais, loops, cursores e / ou outra lógica de não consulta, você está errado. E muitos SPs, funções e gatilhos em DBs em todo o ciberespaço têm esses elementos extras.
12111 KeithS
5

Uma das coisas que as pessoas parecem não perceber é que fazer todo o processamento no servidor SQL não é necessariamente bom, independentemente dos efeitos na qualidade do código.

Por exemplo, se você precisar coletar alguns dados e depois computar algo dos dados, armazene-os no banco de dados. Existem duas opções:

  • Pegue os dados no seu aplicativo, calcule dentro do seu aplicativo e envie-os de volta ao banco de dados
  • Crie um procedimento armazenado ou similar para capturar os dados, calculá-los e armazená-los de uma única chamada para o servidor SQL.

Você pode pensar que a segunda solução é sempre a mais rápida, mas isso definitivamente não é verdade. Estou ignorando, mesmo que o SQL não seja adequado para o problema (por exemplo, manipulação de expressões regulares e expressões regulares). Vamos fingir que você tem o SQL CLR ou algo semelhante para ter uma linguagem poderosa no banco de dados. Se demorar 1 segundo para fazer uma viagem de ida e volta e obter os dados e 1 segundo para armazená-lo, e 10 segundos para fazer o cálculo entre eles. Você está fazendo errado se estiver fazendo tudo no banco de dados.

Claro, você raspa 2 segundos. No entanto, você preferiu desperdiçar 100% de (pelo menos) um núcleo da CPU no servidor de banco de dados por 10 segundos ou preferiu perder esse tempo no servidor da web?

Os servidores da Web são fáceis de expandir, por outro lado, os bancos de dados são extremamente caros, especialmente os bancos de dados SQL. Na maioria das vezes, os servidores da Web também são "sem estado" e podem ser adicionados e removidos por capricho, sem configuração adicional para nada além do balanceador de carga.

Portanto, pense não apenas em reduzir 2 segundos de uma operação, mas também em escalabilidade. Por que desperdiçar um recurso caro, como os recursos do servidor de banco de dados, quando você pode usar os recursos muito mais baratos do servidor da web com um impacto no desempenho relativamente pequeno

Earlz
fonte
1
você também está esquecendo as viagens à rede - não é possível escalar horizontalmente adicionando servidores sem um pouco de eficiência. Portanto, reduzir a carga de dados adicionando uma cláusula where é óbvio - mas as outras operações sql não reduzirão necessariamente o desempenho. Porém, seu argumento está correto em geral, mas não no ponto em que você trata o banco de dados como um armazenamento de dados estúpido. O aplicativo mais escalável que já trabalhei usou procedimentos armazenados para todas as chamadas de dados (exceto duas consultas complexas). Uma terceira solução é a melhor - "proc armazenado para coletar apenas os dados necessários", sem ter certeza se você quis dizer isso como 'computação' ou não.
gbjbaanb
4

Eu gosto de ver como o SQL deve lidar apenas com os dados em si. As regras de negócios que decidem a aparência da consulta podem acontecer no código. A regex ou validação das informações deve ser feita em código. O SQL deve ser deixado apenas para ingressar na sua tabela, consultar seus dados, inserir dados limpos etc.

O que é passado para o SQL deve ser dados limpos e o SQL não precisa realmente saber mais nada do que o necessário para armazená-lo, atualizá-lo, excluí-lo ou recuperar algo. Vi muitos desenvolvedores quererem lançar sua lógica de negócios e codificação em SQL porque pensam nos dados como seus negócios. Desacoplar sua lógica dos dados e você descobrirá que seu código fica mais limpo e fácil de gerenciar.

Apenas os meus US $ 0,02.

Stanley Glass Jr
fonte
Por que você executaria uma regex ou validação de dados que já estão no banco de dados? Restrições devem evitar que dados ruins de nunca chegar lá, eo uso de regex provavelmente significa que você precisa colunas mais úteis ..
Brendan Longo
Eu não estava dizendo que usaria regex ou validação em dados provenientes do banco de dados. Eu acho que eu deveria ter esclarecido que era para dados indo para o banco de dados. Meu argumento foi que os dados devem ser limpos e validados antes de chegar ao DAL.
Stanley vidro Jr
3

Geralmente, eu concordo que o código deve controlar a lógica de negócios e o banco de dados deve ser um hash livre de lógica. Mas aqui estão alguns contrapontos:

Restrições primárias, de chave estrangeira e obrigatórias (não nulas) podem ser aplicadas pelo código. Restrições são lógicas de negócios. Eles devem ser deixados de fora do banco de dados, pois duplicam o código que podem fazer?

Outras partes fora do seu controle tocam o banco de dados? Nesse caso, aplicar restrições próximas aos dados é bom. O acesso pode ser restrito a um serviço da Web que implementa a lógica, mas isso pressupõe que você estava lá "primeiro" e tem o poder de impor o uso do serviço a outras partes.

Seu ORM executa uma inserção / atualização separada para cada objeto? Se sim, você terá sérios problemas de desempenho ao processar em lote grandes conjuntos de dados. Definir operações é o caminho a percorrer. Um ORM terá problemas para modelar com precisão todos os possíveis conjuntos unidos nos quais você pode executar operações.

Você considera uma "camada" uma divisão física por servidores ou uma divisão lógica? A lógica de execução em qualquer servidor teoricamente ainda pode se enquadrar na sua camada lógica. Você pode organizar a divisão compilando em DLLs diferentes, em vez de dividir servidores exclusivamente. Isso pode aumentar drasticamente o tempo de resposta (mas sacrificando a produção), mantendo a separação de preocupações. Uma DLL dividida poderia ser posteriormente movida para outros servidores sem uma nova compilação para aumentar a taxa de transferência (ao custo do tempo de resposta).

mike30
fonte
por que o voto negativo?
mike30
5
Não diminuí a votação, mas qualquer especialista em banco de dados dirá que, considerando o banco de dados, um hash livre de lógica é uma péssima idéia. Causa problemas de integridade de dados ou problemas de desempenho ou ambos.
HLGEM 23/10/12
1
@HLGEM. A resposta descreve os motivos para manter a lógica no banco de dados ou no servidor DB. Ainda não explica isso.
mike30
Eles podem não ter chegado aos contrapontos como eu fiz, e é por isso que não diminuí o voto.
HLGEM 23/10/12
3

O idioma tem mais a ver com manter as regras de negócios, os dados e as relações (os dados, a estrutura e os relacionamentos.) Não é um balcão único para todos os problemas, mas ajuda a evitar coisas como manualmente contadores de registros mantidos, integridade de relacionamento mantida manualmente etc, se essas coisas estiverem disponíveis no nível do banco de dados. Portanto, se alguém aparecer e estender os programas ou gravar outro programa que interaja com o banco de dados, eles não precisarão descobrir como manter a integridade do banco de dados a partir do código anterior. O caso de um contador de registros mantido manualmente é particularmente pertinente quando outra pessoa deseja criar um novo programa para interagir com o mesmo banco de dados. Mesmo se o programa recém-criado tiver exatamente o código certo para o contador, o programa original e o novo em execução aproximadamente ao mesmo tempo provavelmente o corrompem. Existe até código lá fora, que recupera registros e verifica condições antes de gravar um registro novo ou atualizado (no código ou em consultas separadas), quando, se possível, isso geralmente pode ser alcançado diretamente na instrução de inserção ou atualização. A corrupção de dados pode resultar novamente. O mecanismo de banco de dados garante atomicidade; é garantido que uma consulta de atualização ou inserção com condições afeta apenas os registros que atendem às condições e nenhuma consulta externa pode alterar os dados na metade da atualização. Existem muitas outras circunstâncias em que o código é usado quando o mecanismo de banco de dados seria melhor. É tudo sobre integridade de dados e não sobre desempenho. s mesmo código lá fora, que recupera registros e verifica condições antes de gravar um registro novo ou atualizado (no código ou em consultas separadas), quando, se possível, isso geralmente pode ser alcançado diretamente na instrução de inserção ou atualização. A corrupção de dados pode resultar novamente. O mecanismo de banco de dados garante atomicidade; é garantido que uma consulta de atualização ou inserção com condições afeta apenas os registros que atendem às condições e nenhuma consulta externa pode alterar os dados na metade da atualização. Existem muitas outras circunstâncias em que o código é usado quando o mecanismo de banco de dados seria melhor. É tudo sobre integridade de dados e não sobre desempenho. s mesmo código lá fora, que recupera registros e verifica condições antes de gravar um registro novo ou atualizado (no código ou como consultas separadas), quando, se possível, isso geralmente pode ser alcançado diretamente na instrução de inserção ou atualização. A corrupção de dados pode resultar novamente. O mecanismo de banco de dados garante atomicidade; é garantido que uma consulta de atualização ou inserção com condições afeta apenas os registros que atendem às condições e nenhuma consulta externa pode alterar os dados na metade da atualização. Existem muitas outras circunstâncias em que o código é usado quando o mecanismo de banco de dados seria melhor. É tudo sobre integridade de dados e não sobre desempenho. O mecanismo de banco de dados garante atomicidade; é garantido que uma consulta de atualização ou inserção com condições afeta apenas os registros que atendem às condições e nenhuma consulta externa pode alterar os dados na metade da atualização. Existem muitas outras circunstâncias em que o código é usado quando o mecanismo de banco de dados seria melhor. É tudo sobre integridade de dados e não sobre desempenho. O mecanismo de banco de dados garante atomicidade; é garantido que uma consulta de atualização ou inserção com condições afeta apenas os registros que atendem às condições e nenhuma consulta externa pode alterar os dados na metade da atualização. Existem muitas outras circunstâncias em que o código é usado quando o mecanismo de banco de dados seria melhor. É tudo sobre integridade de dados e não sobre desempenho.

Portanto, é realmente um bom idioma de design ou regra de ouro. Nenhuma quantidade de desempenho ajudará em um sistema com dados corrompidos.

Chris
fonte
0

Como mencionado anteriormente, o objetivo é enviar e receber o mínimo possível do banco de dados, porque as viagens de ida e volta são muito caras em termos de tempo. O envio repetido de instruções SQL é uma perda de tempo, especialmente em consultas mais complexas.

O uso de procedimentos armazenados no banco de dados permite que os desenvolvedores interajam com o banco de dados como uma API, sem se preocupar com o esquema complexo na parte traseira. Também reduz os dados enviados ao servidor, pois apenas o nome e alguns parâmetros são enviados. Nesse cenário, a maioria da lógica de negócios ainda pode estar no código, mas não na forma de SQL. O código prepararia essencialmente o que deve ser enviado ou solicitado a partir do banco de dados.

Laurent Goderre
fonte
0

Há algumas coisas a serem lembradas:

  • Um banco de dados relacional deve garantir a integridade referencial por meio de chaves estrangeiras
  • Escalar um banco de dados pode ser difícil e caro. Escalar um servidor da Web é muito mais fácil simplesmente adicionando mais servidores da Web. Divirta-se tentando adicionar mais poder ao servidor SQL.
  • Com C # e LINQ, você pode fazer suas "junções" e outros enfeites através do código, para obter o melhor dos dois mundos em muitos casos
Joe Phillips
fonte
0

"Otimização prematura é a raiz de todo mal" - Donald Knuth

Use a ferramenta mais apropriada para o trabalho. Para integridade dos dados, esse geralmente é o banco de dados. Para regras de negócios avançadas, este é um sistema baseado em regras como o JBoss Drools. Para visualização de dados, essa seria uma estrutura de relatório. etc.

Se você tiver algum problema de desempenho, verifique se algum dado pode ser armazenado em cache ou se uma implementação no banco de dados seria mais rápida. Em geral, o custo de compra de servidores extras ou de energia na nuvem será muito menor do que o custo adicional de manutenção e o impacto de bugs extras.

parasietje
fonte