O banco de dados aciona o mal? [fechadas]

187

Os gatilhos do banco de dados são uma má ideia?

Na minha experiência, eles são maus, porque podem resultar em efeitos colaterais surpreendentes e são difíceis de depurar (especialmente quando um gatilho dispara outro). Muitas vezes, os desenvolvedores nem pensam em procurar se há um gatilho.

Por outro lado, parece que se você tem uma lógica que deve ocorrer sempre que um novo FOOé criado no banco de dados, o local mais seguro é colocar um gatilho de inserção na tabela FOO.

A única vez que estamos usando gatilhos é para coisas realmente simples, como definir o ModifiedDate.

WW.
fonte
31
Esta é uma pergunta totalmente legítima, mas não gosto muito do título sensacionalista. Penso em algo como "Quais são as questões mais importantes a considerar ao implementar gatilhos de banco de dados?" seria muito melhor.
Tamas Czinege 20/01/09
2
A questão está encerrada para adicionar respostas, mas consulte também Os acionadores de banco de dados são seguros para restrições de integridade entre tabelas? . (Spoiler: Não, eles não são)
Mifeet
16
Este site me irrita muito. Esta é uma GRANDE questão, mas, como muitas outras, está fechada porque as pessoas não têm imaginação para aceitar perguntas que não se encaixam no formato binário primitivo de perguntas e respostas que, por algum motivo estranho, se sentem obrigadas a seguir.
Quibblesome
1
A lógica de negócios em um gatilho é problemática (má, se você desejar). A lógica do banco de dados em um gatilho não é problemática (integridade, log).
Greg Gum
1
Eu gosto de confiar no IDE para navegação de código e entender o que está acontecendo. Não posso fazer isso se metade da lógica estiver no banco de dados e a outra metade na linguagem de programação de sua escolha. Em vez de gatilhos, acho mais fácil criar um controlador pelo qual todas as solicitações sejam submetidas. Todos os 'gatilhos' podem ser aplicados lá.
Muhammad Umer

Respostas:

147

Os principais problemas com gatilhos são

  • Eles são completamente globais - eles se aplicam independentemente do contexto da atividade da tabela;
  • Eles são furtivos; é fácil esquecer que eles estão lá até machucá-lo com consequências não intencionais (e muito misteriosas).

Isso apenas significa que eles precisam ser usados ​​com cuidado nas circunstâncias adequadas; que na minha experiência é limitado a problemas de integridade relacional (às vezes com granularidade mais fina do que você pode obter declarativamente); e geralmente não para fins comerciais ou transacionais. YMMV.

dkretz
fonte
20
Essas são duas vantagens, em alguns casos.
Johnno Nolan
18
"Stealthy" é uma ótima palavra, sim - bem dito. É exatamente por isso que eu me afasto deles: muitas vezes são esquecidos ou ignorados. Na minha experiência pessoal, revisitar os gatilhos geralmente é acompanhado por um tapa na minha própria testa.
Christian Nunciato
5
Global é por isso que eles são bons e necessários para a integridade dos dados e coisas como auditoria. Não é um sinal de menos, é uma vantagem.
HLGEM
4
Então, @ RobertŠevčík-Robajz, você está dizendo que todos os desenvolvedores que conhece são incomuns?
HLGEM
3
@HGLEM, concorda que deve haver um especialista para descobrir os gatilhos. Cenário da vida real - não existe. Cenário da vida real - dias passados ​​tentando identificar um bug relacionado a um gatilho esquecido. Cenário da vida real - a lógica do gatilho está sendo desesperadamente empurrada para a lógica do aplicativo, onde pode ser facilmente refatorada e testada em unidade. É a vida real com a qual lido que me faz dizer "fique longe dos gatilhos" ... não é culpa dos gatilhos, pois não é culpa das pedras que as janelas se quebram.
Rbjz
80

Não, eles são realmente uma boa ideia. Se houver um problema com seus gatilhos específicos, você não os fará corretamente, mas isso geralmente significa que há um problema com sua implementação, não o conceito de gatilhos :-).

Usamos muito os gatilhos, porque coloca a atividade específica do DBMS sob o controle do banco de dados ao qual ele pertence. Os usuários de um SGBD não precisam se preocupar com esse tipo de coisa. A integridade dos dados está no próprio banco de dados, não nos aplicativos ou usuários que os utilizam. Sem restrições, gatilhos e outros recursos no banco de dados, os aplicativos devem aplicar as regras e são necessários apenas um aplicativo / usuário não autorizado ou com bugs para destruir os dados.

Por exemplo, sem gatilhos, coisas maravilhosas como colunas geradas automaticamente não existiriam e você teria que processar uma função em cada linha ao selecioná-las. É provável que isso prejudique o desempenho do DBMS, muito melhor criar a coluna gerada automaticamente no momento da inserção / atualização, pois é a única vez que ela muda.

Além disso, a falta de acionadores impediria que as regras de dados fossem aplicadas no DBMS, como pré-acionadores, para garantir que as colunas tenham um formato específico. Observe que isso é diferente das regras de integridade de dados, que geralmente são apenas pesquisas de chave estrangeira.

paxdiablo
fonte
9
"processa uma função em cada linha ao selecioná-las". É melhor usar um índice baseado em funções para esse fim do que um gatilho.
tuinstoel
10
Não necessariamente, o gatilho provavelmente será executado apenas quando a linha for inserida ou atualizada. O índice baseado em função será executado para cada seleção. Dependendo do padrão de uso, um provavelmente é melhor que o outro. Mas nem sempre é melhor que o outro.
21410 jmucchiello
@tuinstoel: Eu tenho que concordar com sua declaração algumas vezes. O Oracle, por exemplo, criará apenas índices baseados em funções se puder provar que a função é determinística. Às vezes, isso simplesmente não pode ser provado (por exemplo, se a função envolver uma pesquisa de uma tabela, mesmo se você souber que os dados da tabela nunca mudam).
Adam Paynter
50

Ferramentas nunca são más. Aplicações dessas ferramentas podem ser más.

Andy Webb
fonte
11
Eu nunca estive mais em conflito depois de ler um comentário. Por um lado, sou a favor da segunda emenda e acredito que as armas não são inerentemente más: é a pessoa que as usa. Por outro lado, acredito que gatilhos são maus ... Eu acho que estou tendo um colapso existencial ...
vbullinger
37
@vbullinger armas não são maus, mas seus gatilhos são;)
Darragh Enright
2
: D As generalizações são perigosas (recursivamente). Você conheceu as 'ferramentas' de tortura usadas pelos inquisidores para 'desencadear' uma confissão? +1 para a perspectiva de qualquer maneira.
Rbjz
22

Concordo. Os problemas com gatilhos são pessoas, não gatilhos. Embora seja mais para olhar, mais para considerar e aumentar o ônus dos codificadores que verificam as coisas corretamente, não descartamos índices para tornar nossa vida mais simples. (Índices ruins podem ser tão ruins quanto gatilhos ruins)

A importância dos gatilhos (na minha opinião) é que ...
- Qualquer sistema sempre deve estar em um estado válido
- O código para aplicar esse estado válido deve ser centralizado (não gravado em todos os SP)

Do ponto de vista da manutenção, um gatilho é muito útil para codificadores concorrentes e problemas para os mais jovens / amadores. No entanto, essas pessoas precisam aprender e crescer de alguma forma.

Eu acho que tudo se resume ao seu ambiente de trabalho. Você tem pessoas confiáveis ​​que aprendem bem e que podem ser metódicas? Caso contrário, você aparentemente tem duas opções:
- Aceite que precisará perder a funcionalidade para compensar
- Aceite que precisa de pessoas diferentes ou que tenha melhor treinamento e gerenciamento

Eles parecem duros, e acho que são. Mas é a verdade básica, em minha mente ...

MatBailie
fonte
3
>>> Os problemas com gatilhos são pessoas. Sim, se apenas as pessoas pudessem codificar na montagem, trabalhar com uma GUI de baixa qualidade, adivinhar corretamente se empurravam ou puxavam uma porta mal projetada ... Qualquer "recurso" que as pessoas cometam repetidamente errado é "mau".
Fakrudeen
1
@Fakrudeen, qualquer desenvolvedor que errar nos gatilhos é incompetente em acessar um banco de dados.
HLGEM
21

Eu acho que gatilhos não são apenas maus, mas necessários para o bom design do banco de dados. Os programadores de aplicativos pensam que os bancos de dados são afetados apenas por seus aplicativos. Eles estão frequentemente errados. Se a integridade dos dados deve ser mantida, não importa de onde a alteração ocorreu, os acionadores são um requisito e é tolice evitá-los, porque alguns programadores são etnocêntricos demais para considerar que algo diferente de seu aplicativo premiado pode estar afetando as coisas. Não é difícil projetar, testar ou solucionar problemas de um gatilho se você for um desenvolvedor de banco de dados competente. Também não é difícil determinar que um gatilho está causando um resultado inesperado se ocorrer a você (como acontece comigo) olhar para lá. Se eu receber um erro dizendo que uma tabela que não estou referenciando no meu sp tem um erro FK, Eu sei, mesmo sem pensar, que o gatilho está causando o problema e qualquer desenvolvedor de banco de dados competente. Colocar regras de negócios apenas no aplicativo é a causa número um que eu encontrei de dados incorretos, pois outros não têm idéia de que essa regra existe e a violam em seus processos. As regras centradas em dados pertencem ao banco de dados e os gatilhos são essenciais para aplicar as mais complexas.

HLGEM
fonte
1
As regras centradas em dados pertencem ao banco de dados
04/06/19
me tevesome programmers are too ethnocentric to consider that something other than their prized application may be affecting things
Kid101
13

Principalmente sim.

A dificuldade com um gatilho é que ele faz coisas "nas suas costas"; o desenvolvedor que mantém o aplicativo pode facilmente não perceber que está lá e fazer alterações que estragam tudo sem nem perceber.

Ele cria uma camada de complexidade que apenas adiciona trabalho de manutenção.

Em vez de usar um gatilho, geralmente pode ser feito um procedimento / rotina armazenado para fazer a mesma coisa, mas de maneira clara e sustentável - chamar uma rotina armazenada significa que o desenvolvedor pode examinar seu código-fonte e ver exatamente o que está acontecendo.

MarkR
fonte
12
Esta é a vantagem de um gatilho, não a desvantagem! Não é possível garantir que os procs armazenados sejam invocados para cada alteração nos dados. Existem muitas maneiras pelas quais os dados podem ser alterados além da GUI.
HLGEM 21/01/09
2
HLGEM, isso depende do seu controle de acesso. Você pode negar qualquer modificação nas tabelas diretamente, exceto por meio de um procedimento armazenado.
Rbjz 18/05
1
Eu acho que o ponto é que, por exemplo, se os registros em duas tabelas SEMPRE devem ser criados e destruídos juntos, não importa como você acessa o banco de dados, e não importa quem você é ou quais permissões você possui, então os acionadores são a única solução legítima . O simples fato de ser possível atribuir permissões demais ou incorretas e esperar que as pessoas saibam quais procedimentos armazenados devem ser usados ​​significa que o banco de dados corre o risco de perder sua integridade. É exatamente o mesmo que relacionamentos com chaves estrangeiras. É simplesmente o melhor e mais confiável imposto pelo mecanismo de banco de dados.
Triynko 17/10
2
Se os registros sempre devem ser criados / destruídos juntos, crie uma restrição de verificação que garanta que eles sejam. Dessa forma, alguém que quebra as regras recebe um erro, em vez de um comportamento oculto que magicamente corrige as coisas sem seu conhecimento ou consentimento.
Mark19
9

Os gatilhos são extremamente poderosos e úteis, há vários cenários em que um gatilho é a melhor solução para um problema.

Eles também são uma ferramenta muito boa de "hack". Muitas vezes, há situações em que você não está no controle imediato do código e do banco de dados. Se você precisar esperar 2 meses para a próxima versão principal do seu código, ainda poderá aplicar um patch ao seu banco de dados imediatamente, poderá acionar uma tabela para executar algumas funcionalidades adicionais. Quando a liberação do código for possível, você poderá substituir esse gatilho pela sua versão codificada da mesma funcionalidade, se desejar.

No final do dia, tudo é "mau" se você não sabe o que está fazendo. Decidir que os gatilhos são porque existem desenvolvedores que não os entendem é o mesmo que argumentar que os carros são maus porque algumas pessoas não podem dirigir ...

Robin Day
fonte
7

Os gatilhos têm seus usos - registrar / auditar e manter uma data de "última modificação" são dois usos muito bons mencionados nas respostas anteriores.

No entanto, um dos princípios básicos do bom design é que as regras de negócios / lógica de negócios / como você deseja chamá-lo devem estar concentradas em um único local. Colocar parte da lógica no banco de dados (por meio de gatilhos ou procs armazenados) e parte do aplicativo viola esse princípio. Duplicar a lógica nos dois lugares é ainda pior, pois eles invariavelmente ficam fora de sincronia.

Há também a questão do "princípio da menor surpresa" que já foi mencionada.

Dave Sherohman
fonte
3
Correto, deve estar em um só lugar, o banco de dados. A lógica que afeta a integridade dos dados deve SEMPRE estar no banco de dados e nunca em um aplicativo em que possa ou não ser chamado ao afetar os dados no banco de dados.
HLGEM
1
@HLGEM: Isso depende se o banco de dados pode ter acesso a informações que lhe permitam dizer se os dados são válidos. Nem sempre é o caso que pode; quando o validador estiver em outra organização (por exemplo, para detalhes do cartão de crédito ou da conta bancária), o banco de dados não saberá se está certo - supondo que esse não seja o banco de dados do banco! - e terá que confiar no pedido de execução. O que você não quer é que o banco de dados faça conexões aleatórias com serviços de terceiros, pois isso é ruim quando se trata da implantação do servidor.
Donal Fellows
@HLGEM: Embora eu não esteja pronto para descartar completamente a opção de colocar toda a lógica do aplicativo no banco de dados, acho que tende a funcionar melhor para colocá-lo em outro lugar, geralmente uma camada OO reutilizável que pode ser usada para todos os aplicativos que acessam o banco de dados. Desde que seu aplicativo acesse apenas o banco de dados através da camada de objetos, as mesmas garantias da lógica sempre sendo chamada ainda serão aplicadas.
Dave Sherohman
2
Nunca trabalhei em um aplicativo de negócios que apenas inseria dados no banco de dados através da camada Objeto e não gostaria de trabalhar em um. É estúpido colocar milhões de importações ou atualizações de todos os preços por meio de um processo projetado para lidar com apenas um registro por vez. A camada Objeto é exatamente o lugar errado para reforçar a integridade dos dados, e é por isso que tantas bases de dados têm problemas de integridade.
HLGEM
@HLGEM Por esse motivo, estou trabalhando em uma extensão do nosso ORM para funcionar como um gatilho usando um conjunto de alterações de tudo dentro de uma transação. Parece um pouco tolo, mas nos impede de ter toda a lógica de negócios no aplicativo, exceto nas poucas vezes em que não é (apenas algumas tabelas precisam de atualização em massa). Também permitirá que todos os desenvolvedores os escrevam e os usem na linguagem com a qual mais se sentem confortáveis ​​e onde haja acesso a todas as abstrações de objetos que criamos.
Adamantish
6

Os gatilhos são uma boa ferramenta quando usados ​​corretamente. Especialmente para auditoria de alterações, preenchimento de tabelas de resumo etc.

Agora eles podem ser "maus" se você acabar no "inferno do gatilho" com um gatilho que desencadeia outros gatilhos. Certa vez, trabalhei em um produto COTS onde eles tinham o que chamavam de "gatilhos flexíveis". Esses gatilhos foram armazenados em uma tabela quando compiladas picadas sql dinâmicas cada vez que são executadas. Os gatilhos compilados examinariam e verificariam se essa tabela tinha algum gatilho flexível para executar e, em seguida, compilar e executar o gatilho "flex". Em teoria, isso soou como uma ideia muito legal porque o produto foi facilmente personalizado, mas a realidade era que o banco de dados praticamente explodiu devido a todas as compilações que ele tinha que fazer ...

Então, sim, eles são ótimos se você mantiver o que está fazendo em perspectiva. Se for algo bem simples como auditoria, resumo, seqüenciamento automático, etc., sem problemas. Lembre-se da taxa de crescimento da tabela e de como o gatilho afetará o desempenho.

tmeisenh
fonte
6

Em um nível alto, existem dois casos de uso para gatilhos1

1) Para fazer coisas "automagicamente" acontecerem. Nesse caso, os gatilhos causam um efeito colateral, eles alteram os dados de maneiras que não eram esperadas, devido à inserção, atualização ou exclusão do operador (primitivo) que foi executado e causou o disparo do gatilho.

O consenso geral aqui é que os gatilhos são realmente prejudiciais. Porque eles alteram a semântica conhecida de uma instrução INSERT, UPDATE ou DELETE. A alteração da semântica desses três operadores SQL primitivos morderá outros desenvolvedores que, mais tarde, no futuro, precisam trabalhar em suas tabelas de banco de dados que não se comportam mais das maneiras esperadas quando operadas com as primitivas SQL.

2) Para impor regras de integridade de dados, além daquelas com as quais podemos lidar declarativamente (usando CHECK, PRIMARY KEY, UNIQUE KEY e FOREIGN KEY). Nesse caso de uso, todos os gatilhos são QUERY (SELECT) para verificar se a alteração que está sendo feita pelo INSERT / UPDATE / DELETE é permitida ou não. Assim como restrições declarativas fazem por nós. Somente neste caso nós (os desenvolvedores) programamos a aplicação.

O uso de gatilhos para o último caso de uso não é prejudicial.

Estou escrevendo sobre isso em: http://harmfultriggers.blogspot.com

Toon Koppelaars
fonte
Ao usar gatilhos para integridade referencial, é mais difícil do que parece lidar com problemas de simultaneidade.
WW.
2
Acordado. Mas é mais fácil usar outros meios?
Toon Koppelaars
Eu diria que o número um só é prejudicial se você tiver desenvolvedores incompetentes.
HLGEM
Existem muitos desenvolvedores incompetentes, apesar de lol.
tabela de dispersão
5

Conheço desenvolvedores que pensam que os gatilhos sempre devem ser usados ​​onde é a maneira mais direta de alcançar a funcionalidade que desejam e desenvolvedores que nunca o farão. É quase como um dogma entre os dois campos.

No entanto, eu pessoalmente concordo completamente com o MarkR - você pode (quase) sempre escrever um código funcionalmente equivalente ao gatilho que será mais visível e, portanto, mais fácil de manter.

DanSingerman
fonte
Exceto que nem todo o trabalho para atingir um banco de dados flui através do código do aplicativo.
HLGEM
5

Não é mau. Eles realmente simplificam coisas como

1.Logging / auditoria de alterações em registros ou mesmo esquemas de banco de dados

Você pode ter um gatilho no ALTER TABLE que reverte as alterações no seu ambiente de produção. Isso deve impedir qualquer modificação acidental da tabela.


2.Reforço da intrgridade referencial (relacionamentos de chave primária / estrangeira etc.) em vários bancos de dados

Chris
fonte
Você pode reverter instruções DDL?
7119 Andrew Swan
Geralmente não. A única maneira de impedir isso é remover essa permissão dos logins dos usuários.
precisa saber é o seguinte
Em alguns mecanismos de banco de dados, você pode (por exemplo, PostgreSQL).
Nicolás
@ Andrew - No SQL Server você pode. O SQL Server 2005+ também possui gatilhos DDL que disparam em eventos como ALTER TABLE.
Martin Smith
4

Nah, eles não são maus - eles são apenas incompreendidos :-D

Os gatilhos têm um uso válido, mas com muita frequência como um retro-hack que acaba piorando as coisas.

Se você estiver desenvolvendo um banco de dados como parte de um aplicativo, a lógica deve sempre estar no código ou sprocs que fazem a chamada. Os gatilhos levarão à dor de depuração mais tarde.

Se você entender como o bloqueio, o impasse e como os DBs acessam os arquivos no disco, o uso de gatilhos da maneira correta (por exemplo, auditoria ou arquivamento do acesso direto ao DB) pode ser realmente valioso.

Keith
fonte
4

Dizer que eles são maus é um exagero, mas eles podem causar malhas. Quando o disparo de um gatilho faz com que outros disparem, torna-se realmente complicado. Digamos que eles sejam problemáticos: http://www.oracle.com/technology/oramag/oracle/08-sep/o58asktom.html

Fazer lógica de negócios no Oracle com gatilhos é mais difícil do que parece devido a problemas de simultaneidade múltipla. Você não vê alterações em outra sessão até que as outras sessões sejam confirmadas.

tuinstoel
fonte
4

Definitivamente, eles não são maus. Achei gatilhos preciosos durante a refatoração de esquemas de banco de dados, renomeando uma coluna ou dividindo-a em duas colunas ou vice-versa (exemplo: caso de nome / sobrenome) e ajudando na transição.

Eles também são muito úteis para auditoria.

Stefano Borini
fonte
4

Esta resposta se aplica especificamente ao SQL Server. (embora possa também se aplicar a outros RDBMSs que eu não tenho ideia. Eu preferiria dar como resposta aqui, mas que foi encerrada como uma bobagem disso.)

Um aspecto não mencionado em nenhuma das respostas até agora é a segurança. Como, por padrão, os gatilhos são executados no contexto do usuário que executa a instrução que aciona o gatilho, isso pode causar uma ameaça à segurança, a menos que todos os gatilhos sejam revisados.

O exemplo dado no BOL sob o título " Gerenciando a segurança do acionador " é de um usuário que cria um acionador que contém o código GRANT CONTROL SERVER TO JohnDoe ;para escalar suas próprias permissões.

Martin Smith
fonte
3

Se houver efeitos colaterais, é um problema por design. Em alguns sistemas de banco de dados, não há outra possibilidade de definir um campo de incremento automático, ou seja, para um campo de ID da chave primária.

Xn0vv3r
fonte
3

Eu acho que eles podem ser maus, mas apenas tão maus quanto qualquer outra coisa em desenvolvimento.

Embora eu realmente não tenha muita experiência com eles, eu os tive em um projeto recente em que trabalhei, o que me levou a essa conclusão. O problema que tenho com eles é que eles podem fazer com que a lógica comercial acabe em dois locais, uma biblioteca de códigos e um banco de dados.

Eu vejo isso como um argumento semelhante ao uso de sprocs. Você sempre terá desenvolvedores realmente bons em SQL gravando a lógica de negócios no banco de dados, enquanto pessoas que não são, terão sua lógica de negócios em outro lugar.

Portanto, minha regra geral é analisar qual é a estrutura do seu projeto. Se parece viável ter lógica comercial armazenada no banco de dados, pode ser útil ter gatilhos.

Aaron Powell
fonte
1

De fato, muitas vezes gatilhos estão sendo mal utilizados. Na verdade, na maioria dos casos, você nem precisa deles. Mas isso não os torna necessariamente ruins.

Um cenário que me ocorre em que os gatilhos são úteis é quando você tem um aplicativo herdado para o qual não possui o código fonte e não há como alterá-lo.

ibz
fonte
1

A idéia de gatilhos não é má; limitar o aninhamento de gatilhos é ruim.

alpav
fonte