Database
 sql >> Base de Dados >  >> RDS >> Database

Não gosta de gatilhos de banco de dados? Você simplesmente não sabe como trabalhar com eles!


Ao projetar grandes bancos de dados relacionais, muitas vezes tomamos a decisão de divergir de uma forma normal, ou seja, desnormalização.

As razões para isso podem ser diferentes, como uma tentativa de acelerar o acesso aos dados especificados, restrições da plataforma/framework/ferramentas de desenvolvimento usadas e falta de habilidades de um desenvolvedor/designer de banco de dados.



Estritamente falando, uma referência às restrições do quadro etc. é na verdade uma tentativa de justificar a falta de habilidades.

Os dados desnormalizados são uma vulnerabilidade, através da qual é fácil trazer nosso banco de dados para um estado não consistente (não integral).

O que podemos fazer com isso?

Exemplo


Em um banco de dados, há uma tabela com algumas operações financeiras:recebimento e descarte de fundos em diferentes contas.

Sempre precisamos saber o saldo da conta.

Nos dados normalizados, o saldo do fundo é sempre um valor calculado. Vamos calcular o total dos recebimentos sem debitar.

No entanto, é muito caro calcular o saldo sempre que há muitas operações. Portanto, decidiu-se armazenar o saldo real em uma tabela separada. Como atualizamos os dados nesta tabela?

A solução é "como sempre"


Quase em todos os sistemas de informação com os quais tive de trabalhar, esta tarefa era realizada por uma aplicação externa, que implementava a lógica de negócio. Você tem sorte se o aplicativo for simples e houver apenas um ponto de alteração de dados, a partir do formulário na interface do usuário. No entanto, e se houver algumas importações, APIs, aplicativos de terceiros etc. realizados por pessoas e equipes diferentes? E se houver várias tabelas com totais em vez de uma? E se houver mais de uma tabela com operações?

Está ficando mais difícil monitorar se um desenvolvedor atualizou várias tabelas ao atualizar as operações. Os dados perdem integridade. O saldo da conta não corresponde a operações. Claro, os testes devem revelar tais situações. No entanto, nosso mundo não é ideal.

Acionadores


Como alternativa, os gatilhos são usados ​​para controlar a integridade dos dados desnormalizados.

Ouvi dizer que os gatilhos tornam um banco de dados muito lento, então usá-los não faz sentido.

O segundo argumento foi que toda a lógica está em um aplicativo separado e manter a lógica de negócios em lugares diferentes não é razoável.

Vamos descobrir.

Atrasos


Um gatilho é acionado dentro da transação que modifica os dados na tabela. A transação não pode ser concluída até que o gatilho tenha executado as etapas necessárias. Portanto, a conclusão é que os gatilhos devem ser ‘leves’.

O exemplo da consulta 'pesada' no gatilho é o seguinte:
update totals 
set total = select sum(operations.amount) from operations where operations.account = current_account
where totals.account = current_account

Uma consulta refere-se à tabela com operações e soma o total valor de operações para a conta .

Quando o banco de dados aumenta, essa consulta consumirá cada vez mais tempo e recursos. No entanto, podemos receber o mesmo resultado usando a consulta leve do seguinte tipo:
update totals 
set total = totals.total + current_amount
where totals.account = current_account

Ao adicionar uma nova linha, esse acionador simplesmente aumentará o total pela conta sem calculá-lo. O total não depende da quantidade de dados nas tabelas. Não faz sentido calcular o total novamente, pois podemos ter certeza de que o gatilho é acionado toda vez ao adicionar uma nova operação.

A remoção ou modificação de linhas é processada da mesma maneira. Os gatilhos desse tipo não retardarão as operações, mas garantirão o acoplamento e a integridade dos dados.

Toda vez que eu experimentava “lags” ao adicionar dados a uma tabela com um gatilho, era um exemplo de uma consulta tão “pesada”. Na maioria dos casos, foi possível reescrevê-lo em uma consulta “fácil”.

Lógica de negócios


Devemos distinguir as funções que fornecem integridade de dados da lógica de negócios. Em cada caso, faço uma pergunta se os dados fossem normalizados, precisaríamos de tal função? Se positivo, a função é lógica de negócios. Se negativo, a função é fornecer integridade dos dados. Você pode envolver essas funções em gatilhos.

No entanto, há uma opinião de que é fácil implementar toda a lógica de negócios através de DBMS, como PostgreSQL ou Oracle.

Espero que este artigo ajude a reduzir o número de bugs em seu sistema de informação.

Claro, estou longe de pensar que tudo o que está escrito aqui é a verdade suprema. Na vida real, é claro, tudo é muito mais complicado. Portanto, você deve tomar uma decisão em cada caso específico. Use seu pensamento de engenharia!

P.S.

  • No artigo, chamei a atenção para o único aspecto de usar acionadores como uma ferramenta poderosa.
  • A abordagem descrita no artigo permite evitar índices nas Operações tabela, que, por sua vez, pode acelerar o processo de adição de dados a essa tabela. Em grandes volumes, essa abordagem compensa facilmente o tempo gasto no gatilho.
  • É importante entender quais ferramentas precisamos usar. Nesse caso, você evitará muitos problemas.