Gatilhos SQL e quando ou quando não usá-los.

43

Quando eu estava aprendendo originalmente sobre SQL, sempre me disseram que só use gatilhos se você realmente precisar e opte por usar procedimentos armazenados, se possível.

Infelizmente, naquela época (há alguns anos), eu não estava tão curioso e preocupado com os fundamentos como agora, então nunca perguntei o motivo.

Qual é a opinião das comunidades nisto? É apenas a preferência pessoal de alguém, ou os gatilhos devem ser evitados (assim como os cursores), a menos que haja uma boa razão para eles.

John Mitchell
fonte

Respostas:

32

O artigo da Wikipedia sobre acionadores de banco de dados apresenta uma boa visão geral do que são acionadores e quando usá-los em diferentes bancos de dados.

A discussão a seguir é baseada apenas no SQL Server.

O uso de gatilhos é bastante válido quando seu uso é justificado. Por exemplo, eles têm um bom valor na auditoria (mantendo o histórico dos dados) sem exigir código processual explícito com todos os comandos CRUD em todas as tabelas.

Os gatilhos dão a você controle imediatamente antes dos dados serem alterados e logo após os dados serem alterados. Isso permite:

  • Auditoria conforme mencionado anteriormente
  • Validação e verificação de segurança comercial, se desejado. Devido a esse tipo de controle, você pode executar tarefas como formatação de colunas antes e depois das inserções no banco de dados.

Sempre me disseram que só use gatilhos se você realmente precisar e opte por usar procedimentos armazenados, se possível.

Pode ser que algumas das razões para isso sejam:

  1. Algumas funções que os acionadores costumavam executar nos dias antigos agora podiam ser executadas de outras maneiras, como atualização de totais e cálculo automático em uma coluna.
  2. Você não vê onde o gatilho é chamado examinando apenas o código sem saber que ele existe. Você vê o efeito deles quando vê os dados alterados e, às vezes, é desconcertante descobrir por que a alteração ocorreu, a menos que você saiba que há um gatilho ou mais atuando nas tabelas.
  3. Se você usar vários controles de banco de dados, como CHECK, RI, Triggers em várias tabelas, o fluxo detalhado da transação se tornará complexo para entender e manter. Você precisará saber exatamente o que acontece quando. Novamente, você precisará de boa documentação para isso.

Algumas diferenças entre os procedimentos armazenados acionadores e não acionadores são (entre outros):

  • Um procedimento armazenado sem acionador é como um programa que precisa ser chamado explicitamente a partir do código ou de um agendador ou de um trabalho em lotes, etc., para executar seu trabalho, enquanto que um acionador é um tipo especial de procedimento armazenado que é acionado como um resposta de um evento em vez de ser executada diretamente pelo usuário. O evento pode ser uma alteração de dados em uma coluna de dados, por exemplo.
  • Os gatilhos têm tipos. Gatilhos DDL e gatilhos DML (dos tipos: INSTEAD OF, For e AFTER)
  • Os procedimentos armazenados sem acionamento podem fazer referência a qualquer tipo de objeto; no entanto, para fazer referência a uma exibição, você deve usar os acionadores INSTEAD OF.
  • No SQLServer, você pode ter qualquer número em procedimentos armazenados sem acionador, mas apenas 1 acionador INSTEAD OF por tabela.
NoChance
fonte
8

Os gatilhos são um requisito para regras complexas de integridade de dados. Eles não podem ser aplicados em qualquer lugar, exceto no banco de dados, ou você terá problemas de integridade dos dados.

Eles também são o melhor local para auditoria, a menos que você não queira capturar todas as alterações no banco de dados (que é o problema da auditoria do aplicativo).

Os gatilhos podem causar problemas de desempenho se não forem escritos com cuidado e se os desenvolvedores não tiverem conhecimento suficiente para escrevê-los bem. Isso faz parte de onde eles conseguem o rap.

Os gatilhos geralmente são mais lentos que outros meios de manter a integridade dos dados; portanto, se você puder usar uma restrição de verificação, use-o em vez de um gatilho.

É fácil escrever gatilhos ruins que fazem coisas estúpidas, como tentar enviar e-mails. Deseja realmente não conseguir alterar os registros no banco de dados se o servidor de email cair?

No servidor SQL, os gatilhos operam em um lote de registros. Com muita frequência, os desenvolvedores pensam que precisam lidar apenas com inserções, atualizações ou exclusões de um registro. Esse não é o único tipo de alteração de dados que ocorre em um banco de dados e todos os acionadores devem ser testados sob as condições de 1 alteração de registro e muitas alterações de registro. Esquecer-se de fazer o segundo teste pode levar a gatilhos com desempenho extremamente ruim ou perda de integridade dos dados.

HLGEM
fonte
3

Uso de gatilhos de banco de dados

  1. Para direcionar valores de coluna automaticamente.
  2. Para impor restrições complexas de integridade.
  3. Para impor regras de negócios complexas.
  4. Para personalizar autorizações de segurança complexas.
  5. Para manter tabelas replicadas.
  6. Auditar a modificação de dados.
asha
fonte
2

Outro caso de uso que encontrei pessoalmente é para bancos de dados acessados ​​por mais de um programa. Se você deseja implementar a funcionalidade, mas não reprojetar todos os sistemas, um gatilho é uma solução sensata.

Por exemplo, trabalhei recentemente em um banco de dados que existia anteriormente como apenas um sistema de escritório. Quando um aplicativo da web foi criado para interagir com ele, queríamos implementar um sistema de notificação (semelhante ao stackexchange, por exemplo), que seria acionado por vários eventos, como o processamento de uma transação e assim por diante. Conseguimos implementar um gatilho para que as atualizações no back-end do escritório disparassem um gatilho para criar a notificação para o front-end e informar ao usuário que sua transação havia sido processada pelo escritório.

Matt
fonte
1

Os gatilhos podem ser usados ​​para impor restrições no banco de dados que não podem ser impostas durante a criação do esquema do banco de dados e quaisquer instruções DML.

DEEPAK JADGE
fonte
0

Digamos que você precise enviar dados para um sistema de terceiros quase em tempo real. Sua tabela contém 950 gigabytes de dados, por isso é muito grande para simplesmente enviar a tabela inteira para o aplicativo de terceiros.

Em vez disso, você acumula alterações em uma fila. Algum programa externo enviará periodicamente pequenos lotes de dados na fila.

O sistema possui mais de 2000 procedimentos armazenados. Você também sabe que existem toneladas de sql no código-fonte. Para garantir que a fila seja preenchida corretamente, você precisará pesquisar todos os processos e códigos armazenados e esperar que não perca nada.

Em vez disso, você pode colocar um gatilho na tabela para manter a fila atualizada. Garantido para não perder nada. Uma localização central. Pena de desempenho? Na verdade, não é possível evitar a ocorrência de preencher a fila, seja por gatilho ou externo.

Nesse cenário, eu diria que não usar um gatilho é uma má opção de design. Se mais tarde você desejar usar um novo método de envio de dados (digamos que a fila não esteja funcionando) e a interface mudar, você estará protegido se usar o gatilho. Os gatilhos geralmente são a melhor escolha. Não ouça fanboys dogmáticos anti-gatilho.

Lord Tydus
fonte
Mas definitivamente existem muitas coisas que NÃO devem ser implementadas com um gatilho.
Lord Tydus
-6

Um gatilho que envia email não é necessariamente uma ideia "estúpida". O que é estúpido é não antecipar a interrupção do e-mail no design e manipulá-la normalmente sem perda de dados. A parte 'estúpida' disso é muito ruim para o tratamento inexistente de erros por desenvolvedores preguiçosos que sentem que são imunes a cometer erros.

Eu também ofereceria a observação de que um gatilho pode ser mantido simples, invocando um procedimento / função armazenado que pode ser arbitrariamente complicado e pode ser reutilizável por vários gatilhos ou outros procedimentos armazenados. É por isso que existem pacotes e bibliotecas.

O fanatismo é realmente incapacitante.

ALLEN MARSHALL
fonte
1
Não vejo lugar nenhum na pergunta em que a palavra "email" é mencionada. Você estava tentando responder a outra resposta? Stack Exchange não é um fórum .