Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Normalizando um banco

Bom dia, conversando com o pessoal do serviço surgiu uma dúvida.

Na terceira normalização foi falado que em uma tabela não podemos ter colunas que sejam ou dependam do resultado de outra coluna, mas:

Imagine que estamos lançando uma nota de entrada com 1000 itens, custando 0,1329, precisamos calcular 10% de ICMS e 20% de IPI, nesse caso se não tivermos um campo para o usuário inserir o valor do ICMS e IPI sempre vai dar diferença em saldos na hora de realizar os cálculos.

Como resolver o problema de saldo e ainda manter o banco normalizado ou nesse caso seria uma excessão e não teríamos a tabela normalizada.

OBS: Os valores dos impostos são fictícios.

7 respostas

Oi Matheus, tudo bem? Isso me lembra a questão de atributos calculados. São atributos que você pode ter na sua classe, mas que eles não tem um valor fixo pré-definido.

A idade de um usuário pode ser o exemplo mais simples. Neste caso, você salvaria a data de nascimento e calcularia a idade quando fosse necessária.

Acho que vale o mesmo exemplo pro seu cenário. Faz sentido?

Não Wanderson, a idade aqui não faz sentido algum, é um tipo de coisa simples, nunca irá dar diferença de saldo.

O meu exemplo se encaixa em sistema financeiro, que trabalha com valores, uma bolsa de valores por exemplo ou transação bancária.

Como eu disse no exemplo: Calcular 10% de ICMS de 0,1329, se no meu banco eu gravar apenas a porcentagem do ICMS, eu nunca irei conseguir fazer os relatórios contábeis bater, pois vai haver uma diferença de saldo em questão de arredondamentos, então nesse contexto eu não ia conseguir normalizar minha tabela.

Veja que é algo bem mais complexo do que uma simples conta de subtração como idade de nascimento, aqui estamos falando para sistemas de transação bancária, bolsa de valores, contábil, etc..

Então Matheus, você teria em um outro lugar um histórico da variação do valor do imposto que você teria que guardar. A questão é que, você precisa considerar as datas. Desde que você tenha as datas e o histórico, você pode deixar isso em uma tabela a parte e fazer o comparativo.

Acredito que talvez você não ter compreendido o tipo de abstração que eu tentei fazer, desculpe se não fui tão específico quanto seu exemplo.

Veja que sistemas financeiros precisam trabalhar com históricos de valores, o SELIC de hoje não é o mesmo de amanhã e muito menos o de ontem, por isso que o histórico é importante. Então você vai precisar fazer um match de data da emissão da nota e a data/valor do imposto pra fazer o cálculo.

A outra alternativa é você fazer como mesmo propôs, não normalizar esse ponto. É o bom e velho trade-off, você perde um pouco na normalização, mas ganha na redução da complexidade do banco. Existem outros fatores no longo prazo, mas por hora é isso.

Mas mesmo com o histórico, iriamos acabar tendo o mesmo problema Wanderson, pois haverá a mesma necessidade de ficar recalculando toda hora os valores dos impostos, assim o problema de arredondamento ainda persiste.

solução!

Por isso que eu disse:

A outra alternativa é você fazer como mesmo propôs, não normalizar esse ponto. É o bom e velho trade-off, você perde um pouco na normalização, mas ganha na redução da complexidade do banco. Existem outros fatores no longo prazo, mas por hora é isso.

E completo:

Exceções existem e você me parece estar em uma, visto que, problemas de arredondamento estarão presentes sempre na computação. E se brincar, até na matemática.

Certo, era isso que eu queria saber, o problema já resolvemos faz tempo, mas só queria saber se existia alguma maneira de resolver, mas, mantendo o banco normalizado.

Entendi.

Normalização é como uma boa prática, vale aplicar sempre, ajuda bastante, mas também tem seus limites. Há casos muito específicos onde não vale a pena e há casos que a normalização é até quebrada totalmente por questões de performance.

Fico feliz em ter ajudado, mesmo que pouco.