Pergunta

No passado, nunca fui fã de usar gatilhos em tabelas de banco de dados.Para mim eles sempre representaram alguma "mágica" que iria acontecer no lado do banco de dados, muito longe do controle do código da minha aplicação.Eu também queria limitar a quantidade de trabalho que o banco de dados tinha que realizar, já que geralmente é um recurso compartilhado e sempre presumi que os gatilhos poderiam ficar caros em cenários de alta carga.

Dito isso, encontrei alguns casos em que fazia sentido usar gatilhos (pelo menos na minha opinião, eles faziam sentido).Recentemente, porém, me encontrei em uma situação em que às vezes preciso "ignorar" o gatilho.Eu me senti muito culpado por ter que procurar maneiras de fazer isso, e ainda acho que um design de banco de dados melhor aliviaria a necessidade desse desvio.Infelizmente, esse banco de dados é usado por vários aplicativos, alguns dos quais são mantidos por uma equipe de desenvolvimento pouco cooperativa que gritava sobre mudanças de esquema, então fiquei preso.

Qual é o consenso geral sobre gatilhos?Ama-os?Odeie-os?Você acha que eles têm um propósito em alguns cenários?Você acha que precisar ignorar um gatilho significa que você está "fazendo errado"?

Foi útil?

Solução

Os gatilhos geralmente são usados ​​incorretamente, introduzem bugs e, portanto, devem ser evitados.Nunca projete um gatilho para fazer uma verificação de restrição de integridade que cruze as linhas de uma tabela (por exemplo, "o salário médio por departamento não pode exceder X).

Tom Kyte, o vice-presidente da Oracle indicou que preferiria remover gatilhos como um recurso do Oracle banco de dados por causa de seu papel frequente em bugs.Ele sabe que é apenas um sonho e que os gatilhos vieram para ficar, mas se pudesse ele removeria os gatilhos do Oracle, ele o faria (junto com a cláusula WHEN OTHERS e as transações autônomas).

Os gatilhos podem ser usados ​​corretamente?Absolutamente.

O problema é: eles não são usados ​​corretamente em tantos casos que eu estaria disposto a desistir de qualquer benefício percebido apenas para se livrar dos abusos (e bugs) causados ​​por eles.-Tom Kyte

Outras dicas

Pense em um banco de dados como um grande objeto - após cada chamada para ele, ele deve estar em um estado logicamente consistente.

Os bancos de dados se expõem por meio de tabelas, e manter tabelas e linhas consistentes pode ser feito com gatilhos.Outra maneira de mantê-los consistentes é proibir o acesso direto às tabelas e permiti-lo apenas por meio de procedimentos armazenados e visualizações.

A desvantagem dos gatilhos é que qualquer ação pode invocá-los;isso também é um ponto forte - ninguém vai prejudicar a integridade do sistema por incompetência.

Como contraponto, permitir o acesso a um banco de dados apenas por meio de procedimentos armazenados e visualizações ainda permite o acesso backdoor de permissões.Confia-se que os usuários com permissões suficientes não quebrarão a integridade do banco de dados; todos os outros usam procedimentos armazenados.

Quanto à redução da quantidade de trabalho:os bancos de dados são incrivelmente eficientes quando não precisam lidar com o mundo exterior;você ficaria realmente surpreso com o quanto até a troca de processos prejudica o desempenho.Essa é outra vantagem dos procedimentos armazenados:em vez de uma dúzia de chamadas para o banco de dados (e todas as viagens de ida e volta associadas), há uma.

Agrupar coisas em um único processo armazenado é bom, mas o que acontece quando algo dá errado?Digamos que você tenha 5 etapas e a primeira falhe, o que acontece com as outras etapas?Você precisa adicionar um monte de lógica para atender a essa situação.Depois de começar a fazer isso, você perde os benefícios do procedimento armazenado nesse cenário.

A lógica de negócios precisa ir a algum lugar, e há muitas regras de domínio implícitas incorporadas no design de um banco de dados - relações, restrições e assim por diante são uma tentativa de codificar regras de negócios dizendo, por exemplo, que um usuário só pode ter uma senha.Dado que você começou a inserir regras de negócios no servidor de banco de dados por meio dessas relações e assim por diante, onde traçar o limite?Quando o banco de dados abre mão da responsabilidade pela integridade dos dados e começa a confiar nos aplicativos de chamada e nos usuários do banco de dados para acertar?Os procedimentos armazenados com essas regras incorporadas podem colocar muito poder político nas mãos dos DBAs.Tudo se resume a quantas camadas existirão em sua arquitetura de n camadas;se houver uma camada de apresentação, negócios e dados, onde está a separação entre negócios e dados?Que valor agregado a camada de negócios agrega?Você executará a camada de negócios no servidor de banco de dados como procedimentos armazenados?

Sim, acho que ter que ignorar um gatilho significa que você está “fazendo errado”;neste caso, um gatilho não é para você.

enter image description here

Eu trabalho com aplicativos web e winforms em c# e ODIAR aciona com paixão.Nunca me deparei com uma situação em que pudesse justificar o uso de um gatilho em vez de mover essa lógica para a camada de negócios do aplicativo e replicar a lógica do gatilho lá.

Eu não faço nenhum trabalho do tipo DTS ou algo parecido, então pode haver alguns casos de uso para usar o gatilho lá, mas se alguém em qualquer uma das minhas equipes disser que pode querer usar um gatilho, é melhor ter preparado bem seus argumentos porque me recuso a ficar parado e permitir que gatilhos sejam adicionados a qualquer banco de dados em que estou trabalhando.

Algumas razões pelas quais não gosto de gatilhos:

  • Eles movem a lógica para o banco de dados.Depois de começar a fazer isso, você estará sofrendo muito porque perderá a depuração, a segurança do tempo de compilação e o fluxo lógico.Está tudo ladeira abaixo.
  • A lógica que implementam não é facilmente visível para ninguém.
  • Nem todos os mecanismos de banco de dados suportam gatilhos, portanto sua solução cria dependências em mecanismos de banco de dados

Tenho certeza de que poderia pensar em mais razões de cabeça, mas só essas são suficientes para eu não usar gatilhos.

"Nunca projete um gatilho para fazer uma verificação de restrição de integridade que cruze as linhas de uma tabela" - não posso concordar.A pergunta está marcada como 'SQL Server' e as cláusulas de restrições CHECK no SQL Server não podem conter uma subconsulta;pior, a implementação parece ter uma suposição 'codificada' de que um CHECK envolverá apenas uma única linha, portanto, o uso de uma função não é confiável.Então, se eu precisar de uma restrição que envolva legitimamente mais de uma linha - e um bom exemplo aqui é a chave primária sequenciada em uma tabela temporal clássica de 'tempo válido' onde preciso evitar períodos sobrepostos para a mesma entidade - como posso Eu faço isso sem gatilho?Lembre-se de que esta é uma chave primária, algo para garantir a integridade dos dados, portanto, aplicá-la em qualquer lugar que não seja o SGBD está fora de questão.Até que as restrições CHECK obtenham subconsultas, não vejo uma alternativa ao uso de gatilhos para certos tipos de restrições de integridade.

Os gatilhos podem ser muito úteis.Eles também podem ser muito perigosos.Acho que eles são adequados para tarefas de limpeza doméstica, como preencher dados de auditoria (criados por, data de modificação, etc.) e em alguns bancos de dados podem ser usados ​​para integridade referencial.

Mas não sou um grande fã de colocar muita lógica de negócios neles.Isso pode tornar o suporte problemático porque:

  • é uma camada extra de código para pesquisar
  • às vezes, como o OP aprendeu, quando você precisa corrigir os dados, o gatilho pode estar fazendo coisas com a suposição de que a alteração dos dados é sempre por meio de uma diretiva de aplicativo e não de um desenvolvedor ou DBA corrigindo um problema, ou mesmo de um diferente aplicativo

Quanto a ter que ignorar um gatilho para fazer algo, isso pode significar que você está fazendo algo errado ou que o gatilho está fazendo algo errado.

A regra geral que gosto de usar com gatilhos é mantê-los leves, rápidos, simples e o mais não invasivos possível.

Eu me pego ignorando os gatilhos ao fazer importações de dados em massa.Acho que se justifica em tais circunstâncias.

Porém, se você acabar ignorando os gatilhos com muita frequência, provavelmente precisará dar uma nova olhada no motivo pelo qual os colocou lá.

Em geral, eu votaria em "eles têm um propósito em alguns cenários".Estou sempre nervoso com as implicações de desempenho.

Não sou fã, pessoalmente.Vou usá-los, mas somente quando descobrir um gargalo no código que pode ser resolvido movendo ações para um gatilho.Geralmente, prefiro a simplicidade e uma maneira de manter as coisas simples é manter a lógica em um só lugar – o aplicativo.Também trabalhei em empregos onde o acesso é muito compartimentado.Nesses ambientes, quanto mais código eu coloco em gatilhos, mais pessoas preciso envolver até mesmo para as soluções mais simples.

Usei gatilhos pela primeira vez há algumas semanas.Mudamos um servidor de produção do SQL 2000 para o SQL 2005 e descobrimos que os drivers estavam se comportando de maneira diferente com os campos NText (armazenando um documento XML grande), eliminando o último byte.Usei um gatilho como uma correção temporária para adicionar um byte fictício extra (um espaço) ao final dos dados, resolvendo nosso problema até que uma solução adequada pudesse ser implementada.

Além deste caso especial e temporário, eu diria que os evitaria, pois eles escondem o que está acontecendo, e a função que fornecem deve ser tratada explicitamente pelo desenvolvedor, e não como uma mágica oculta.

Honestamente, a única vez que uso gatilhos para simular um índice exclusivo que pode ter NULL que não conta para a exclusividade.

Quanto à redução da quantidade de trabalho:os bancos de dados são incrivelmente eficientes quando não precisam lidar com o mundo exterior;você ficaria realmente surpreso com o quanto até a troca de processos prejudica o desempenho.Essa é outra vantagem dos procedimentos armazenados:em vez de uma dúzia de chamadas para o banco de dados (e todas as viagens de ida e volta associadas), há uma.

isso é um pouco fora do assunto, mas você também deve estar ciente de que está olhando para isso apenas a partir de um potencial positivo.

Agrupar coisas em um único processo armazenado é bom, mas o que acontece quando algo dá errado?Digamos que você tenha 5 etapas e a primeira falhe, o que acontece com as outras etapas?Você precisa adicionar um monte de lógica para atender a essa situação.Depois de começar a fazer isso, você perde os benefícios do procedimento armazenado nesse cenário.

Fã total,

mas realmente tenho que usá-lo com moderação quando,

  • Necessidade de manter a consistência (especialmente quando tabelas de dimensão são usadas em um warehouse e precisamos relacionar os dados na tabela de fatos com sua dimensão adequada.Às vezes, a linha adequada na tabela de dimensões pode ser muito cara para calcular, então você deseja que a chave seja escrita diretamente na tabela de fatos. Uma boa maneira de manter essa "relação" é com o gatilho.

  • Necessidade de registrar alterações (em uma tabela de auditoria, por exemplo, é útil saber qual @@ usuário fez a alteração e quando ela ocorreu)

Alguns RDBMS, como o sql server 2005, também fornecem gatilhos nas instruções CREATE/ALTER/DROP (para que você possa saber quem criou qual tabela, quando, eliminou qual coluna, quando, etc.)

Honestamente, usando gatilhos nesses três cenários, não vejo por que você precisaria “desativá-los”.

A regra geral é:não use gatilhos.Conforme mencionado anteriormente, eles adicionam sobrecarga e complexidade que podem ser facilmente evitadas movendo a lógica para fora da camada de banco de dados.

Além disso, no MS SQL Server, os gatilhos são disparados uma vez por comando SQL, e não por linha.Por exemplo, a instrução SQL a seguir executará o gatilho apenas uma vez.

UPDATE tblUsers
SET Age = 11
WHERE State = 'NY'

Muitas pessoas, inclusive eu, tiveram a impressão de que os gatilhos são acionados em todas as linhas, mas não é o caso.Se você tiver uma instrução sql como a acima que pode alterar dados em mais de uma linha, você pode querer incluir um cursor para atualizar todos os registros afetados pelo gatilho.Você pode ver como isso pode ficar complicado muito rapidamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top