banco de dados - Desenvolvimento em três camadas - Stack Overflow em Português
Desenvolvimento em três camadas
Num sistema desenvolvido em três camadas, devo deixar alguma consistência para o banco de dados ou devo resolver tudo na camada do meio?
Exemplo: Tenho uma tabela de usuários, onde o nome deve ser único.
nome=João
nome=Carlos
No envio do usuário id=3 o sistema não pode aceitar a inclusão do usuário, mas devo deixar isto para o banco de dados, que tem um índice único para o campo nome, ou devo resolver isto na camada do meio, procurando se o usuário já existe e caso sim retornar uma mensagem para o usuário?
banco-de-dados arquitetura-de-software
editada 5/06/16 às 11:40
perguntada 4/06/16 às 22:26
O termo "desenvolvimento em 3 camadas" é genérico demais para definir alguma coisa. Mesmo que ele definisse seria apenas uma regra a ser seguida sem olhar o contexto do que está efetivamente fazendo. Regra aplicada sem contexto não serve pra muita coisa, chega até atrapalhar.
Dados repetidos é comum deixar que o banco de dados informe porque ele é o mais adequado para saber se realmente há um repetido em todas situações. Em algumas até dá para deixar para outro instrumento fazer isto, mas não há garantias. Tem que fazer certo em qualquer lugar.
Eu vejo muitas vezes o programador verificar se existe e depois decidir o que fazer. Isto é fazer a verificação na aplicação. O correto é mandar o banco de dados fazer o que se deseja (no caso a inclusão) e ver se ele falhou por já existir o usuário cadastrado. Aí se falhar, pode fazer o que quiser, inclusive mandar mensagem para o usuário.
Importante não confundir isto com uma consulta auxiliar, antes da inserção, apenas para evitar o usuário preencher desnecessariamente um cadastro, por exemplo. Mas isto já é um problema de UX.
Isto vale para qualquer tipo de desenvolvimento que envolva um banco de dados, usando qualquer tecnologia, técnica ou metodologia.
editada 17/01/20 às 18:55
respondida 4/06/16 às 22:35
As duas maneiras são válidas no desenvolvimento em 3 camadas.
Apenas alinhando o conceito de três camadas (apesar de ser uma definição clássica, antiga e consolidada, alguém pode não estar familiarizado): as camadas são Interface/Apresentação, Aplicação e Base de dados. A história desta definição e função de cada cada camada, se necessário, pode ser contexto para outra pergunta.
Além destas duas maneiras (validar ou na camada de aplicação ou na camada de banco de dados), existe também uma terceira opção que é validar nas duas camadas.
Explico: dependendo das ferramentas que se está utilizando, pode ser difícil mostrar uma mensagem amigável ao usuário no caso de a duplicidade ser rejeitada apenas pelo banco de dados.
Os sistemas de banco de dados costumam mostrar mensagens do tipo:
"Erro SQL 3344: tentativa de violação do índice único IX_AAAxxxbb09222_01..."
e raramente estas mensagens são úteis para o usuário final.
Mesmo que você tente dar um nome significativo para cada índice ou constraint, a mensagem ainda pode ficar muito estranha - além de que nomes amigáveis nem sempre são possíveis por limitação do próprio banco de dados (tamanho do nome, uso de caracteres especiais, etc.).
Então, quando usar cada uma das três opções:
Validação apenas no banco de dados
Você pode validar apenas no banco de dados quando as chances de violação de constraints forem remotas ou quando o erro de violação de constraint não afetar a interface com o usuário comum (quando o erro só puder ocorrer em cenários de integração, por exemplo).
Se viável, conforme as ferramentas que você utiliza, você também pode validar apenas no banco de dados e se fiar em uma rotina que traduza as mensagens de erro adequadamente, mostrando uma mensagem mais amigável para o usuário final.
Validação apenas no aplicativo
Você pode validar apenas no aplicativo quando o próprio aplicativo tiver condições de garantir a integridade em nível satisfatório.
Se o respeito a constraints for premissa do sistema, validar apenas no aplicativo pode ser um risco alto demais para assumir, além de os benefícios serem poucos pois o banco de dados valida constraints com mais performance que o aplicativo.
O cenário mais comum para não ter constraints no banco de dados é necessidade de alta performance, e nestes casos o sistema é modelado para não depender da garantia de integridade relacional ou unicidade de registros.
Validação no aplicativo e no banco de dados
Esta opção é útil para não deixar o usuário ir muito longe no trabalho dele quando mesmo antes de começar este trabalho já não tem nenhuma condição de ser persistido.
Pode haver regras de negócio específicas que valham o esforço de verificar previamente se as entradas do usuário são válidas para o banco de dados, e avisá-lo adiantamente que ele precisa seguir por outro caminho.
Depois, é claro, no ato da persistência, as constraints do banco ainda entram em cena para garantir a integridade.
É comum um mesmo sistema adotar as três opções, validadando apenas no banco, ou apenas no aplicativo (ou simplesmente não usando constraints) ou validando em ambas as camadas, dependendo de cada requisito.
respondida 6/06/16 às 14:11
17,2mil11 medalhas de ouro3333 medalhas de prata7777 medalhas de bronze
Caramba, gostei da resposta. – Joel 6/06/16 às 15:28
O MVC também e baseado em camadas assim como este padrão? – gato 8/06/16 às 13:59
@drmcarvalho Não necessariamente. MVC está preocupado em isolar as regras de negócio das regras de aplicativo e interface. Veja: você pode desenvolver um aplicativo Três Camadas e misturar na camada do meio, em único componente, as definições de interface com as regras de negócio e de aplicativo. Ainda será Três Camadas mas não será MVC. – Caffé 8/06/16 às 22:12
@drmcarvalho Enquanto, por outro lado, você pode implementar corretamente o MVC codificando todos os componentes na camada do meio. MVC está mais para a separação de responsabilidades em componentes do que em camadas (sejam camadas físicas ou conceituais). – Caffé 8/06/16 às 23:32
@drmcarvalho Mesmo usando MVC você pode ter regras tratadas em mais de uma camada. Veja esta descrição do MVC: pt.stackoverflow.com/a/86132/14584. Repare que "camada" nem foi mencionado. Não existe uma correlação necessária entre MVC e "tiers" ou "layers", nem semelhanças, nem diferenças, nem uma forma específica de distribuir os componentes do MVC entre camadas... São coisas distintas. Compreenda camadas físicas ("tiers"), camadas conceituais ("layers"), e também o MVC. Eventualmente dê uma olhada também nas camadas do DDD. Isso deve clarear as idéias. – Caffé 10/06/16 às 14:57
Esta não é a resposta que você está procurando? Pesquise outras perguntas com a tag banco-de-dados arquitetura-de-software ou faça sua própria pergunta.