Pergunta

Eu estou tentando descobrir se eu deveria estar usando lógica de negócios crítico em um gatilho ou dentro restrição do meu banco de dados.
Até agora eu adicionei lógica em gatilhos como ele me dá o controle sobre o que acontece a seguir e meios eu posso fornecer mensagens de utilizador personalizado em vez de um erro que provavelmente irá confundir os usuários.

Existe algum ganho de desempenho perceptível no uso de restrições sobre gatilhos e quais são as melhores práticas para determinar qual usar.

Foi útil?

Solução

Restrições mãos para baixo!

  • Com as restrições que você especificar princípios relacionais, isto é, fatos sobre seus dados. Você nunca vai precisar alterar suas limitações, a não ser algumas mudanças fato (ou seja, novos requisitos).

  • Com gatilhos você especificar como lidar com dados (em inserções, atualizações etc.). Esta é uma maneira "não-relacional" de fazer as coisas.

Para explicar-me melhor com uma analogia: a maneira correta de escrever uma consulta SQL é especificar "o que você quer" em vez de "como obtê-lo" - deixe a figura RDBMS para fora a melhor maneira de fazer isso por você. O mesmo se aplica aqui:. Se você usar triggers você tem que ter em mente várias coisas como a ordem de execução, transbordante, etc ... Let SQL fazer isso por você com restrições, se possível

Isso não quer dizer que disparadores não têm usos. Eles fazem: às vezes você não pode usar uma restrição para especificar algum fato sobre seus dados. É extremamente raro embora. Se isso acontece com você muito , em seguida, provavelmente há algum problema com o esquema.

Outras dicas

Best Practice : se você pode fazê-lo com uma restrição, use uma restrição.

Triggers não são tão ruins quanto eles ficam descrédito para (se usado corretamente), embora eu sempre usar uma restrição sempre que possível. Em RDMS modernos, a sobrecarga de gatilhos desempenho é comparável a restrições (Claro, isso não significa que alguém não pode colocar código horrendo em um gatilho!).

Ocasionalmente, é necessário usar um gatilho para impor uma restrição 'complexo' como a situação de querer impor que um e apenas um dos dois campos de chave estrangeira de uma tabela são preenchidos (eu vi essa situação em alguns domínio modelos).

O debate sobre se a lógica de negócios deve residir na aplicação em vez do DB, depende em certa medida sobre o ambiente; se você tiver muitos aplicativos que acessam o banco de dados, ambas as restrições e gatilhos pode servir como guarda final que os dados estão corretos.

Os gatilhos podem florescer em um problema de desempenho. Sobre o mesmo tempo que isso acontece eles também se tornou um pesadelo de manutenção. Você não pode descobrir o que está acontecendo e (bônus!) Se comporta de aplicação de forma irregular com problemas de dados "espúrias". [Realmente, eles são questões de gatilho.]

Não há toques do usuário final SQL diretamente. Eles usam programas de aplicação. programas de aplicação contêm lógica de negócios de forma muito mais inteligente e muito mais sustentável do que gatilhos. Coloque a lógica da aplicação em programas de aplicação. Colocar os dados no banco de dados.

A menos que você e seus "usuários" não compartilham uma linguagem comum, você pode explicar as violações de restrição para eles. A alternativa - não explicar -. Transforma um simples banco de dados em um problema porque mistura os dados e o código do aplicativo em um atoleiro unmaintainable

"Como faço para obter garantia absoluta de que todo mundo usando o modelo de dados corretamente?"

técnicas Two (e meia).

  1. Certifique-se de que o modelo é direito : ele combina o domínio do problema do mundo real. Não há hacks ou solução alternativa ou atalhos que só pode ser resolvido através de explicações complexas acenando mão, stored procedures e triggers.

  2. ajudar a definir a camada de modelo de negócio das aplicações. A camada de código do aplicativo que todos compartilham e reutiliza.

    a. Além disso, certifique-se de que a camada de modelo atende às necessidades das pessoas. Se a camada de modelo tem os métodos e coleções certas, há menos incentivo para ignorá-lo para obter acesso directo aos dados subjacente. Geralmente, se o modelo é certo, isso não é uma profunda preocupação.

Triggers são uma espera de trem-destruição acontecer. Restrições não são.

Além das outras razões para usar restrições, o otimizador Oracle pode usar restrições para a sua vantagem.

Por exemplo, se você tem uma restrição dizendo (Amount >= 0) e, em seguida, você consulta com WHERE (Amount = -5) a Oracle sabe imediatamente que não há registros coincidentes.

As restrições e gatilhos são para 2 coisas diferentes. Restrições são usadas para Restringir do domínio (entradas válidas) de seus dados. Por exemplo, um SSN seria armazenada como char (9), mas com uma restrição de [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [ 0-9] [0-9] [0-9] (todo numérico).

Triggers são uma forma de fazer cumprir negócio lógica em seu banco de dados. Tomando SSN novamente, talvez uma trilha de auditoria deve ser mantida sempre que um SSN é alterado - que seria feito com um gatilho,

Em geral, problemas de integridade de dados em um RDBMS moderno pode ser tratado com alguma variação de uma restrição. No entanto, algumas vezes você entrar em uma situação onde a normalização indevido (ou requisitos alterados, resultando na normalização agora imprópria) impede uma restrição. Nesse caso, um gatilho pode ser capaz de impor sua restrição - mas é opaco para o RDBMS, o que significa que não pode ser usado para otimização. É também "escondido" lógica, e pode ser um problema de manutenção. Decidir se refatorar o esquema ou usar um gatilho é uma chamada de julgamento naquele ponto.

De um modo geral eu preferiria restrições e meu código seria detectar erros do SQL Server e apresentar algo mais amigável para o usuário.

@onedaywhen

Você pode ter uma consulta como uma restrição no SQL Server, você apenas tem que ser capaz de se encaixar em uma função escalar: http://www.eggheadcafe.com/software/aspnet/30056435/check-contraints-and-tsql.aspx

@ Mark Brackett: "As restrições são usadas para restringir o domínio ... Triggers são uma forma de impor a lógica de negócios": Não é tão simples no SQL Server porque a funcionalidade dos seus constrangimentos é limitada por exemplo ainda cheia SQL-92. Tomemos o exemplo clássico de uma 'chave primária' seqüenciado em uma tabela de banco de dados temporais: Idealmente, eu usaria uma restrição CHECK com uma subconsulta para evitar períodos sobrepostos para a mesma entidade, mas SQL Server não pode fazer isso, então eu tenho que usar um desencadear. Também ausente do SQL Server é a capacidade SQL-92 para adiar a verificação de restrições, mas ao invés disso eles são (em vigor) verificada após cada declaração SQL, por isso novamente um gatilho pode ser necessário para o trabalho em torno as limitações do SQL Server.

Se em todas as restrições de uso possíveis. Eles tendem a ser slighlty mais rápido. Gatilhos deve ser usado para a lógica complexa que uma restrição não pode manipular. Gatilho escrita é complicado também e se você achar que você deve escrever um gatilho, certifique-se de declarações baseada set Utilize becasue triigers operar contra a inserção todo, atualizar ou excluir (Sim, haverá momentos em que mais de um registro é afetado, o plano sobre isso!), não apenas um registro por vez. Não use um cursor em um gatilho se puder ser evitado.

No que diz se a colocar a lógica no aplicativo em vez de um gatilho ou constrangimento. NÃO FAÇA ISSO!!! Sim, as aplicações devem ter verificações antes de enviar os dados, mas a integridade dos dados e lógica de negócios deve estar no nível de banco de dados ou seus dados vai ficar confuso quando várias aplicações ligar para ele, quando inserções globais são feitas outsiide a aplicação etc. Dados integridade é a chave para bancos de dados e deve ser aplicada no nível de banco de dados.

@Meff: existem problemas potenciais com a abordagem de usar uma função, porque, simplesmente, SQL Server restrições CHECK foram concebidos com uma única linha como unidade de trabalho, e tem falhas quando trabalhando em um conjunto de resultados. Para mais alguns detalhes sobre isso, consulte: [ http://blogs.conchango.com/davidportas/archive/2007/02/19/Trouble-with-CHECK-Constraints.aspx] [1] .

[1]: David Portas' Blog:. Problemas com restrições CHECK

O mesmo que Skliwz. Só para que você saiba um uso canônico de gatilho é a tabela de auditoria. Se muitos procedimentos de atualização / inserir / excluir uma tabela que deseja auditoria (que modificou o quê e quando), o gatilho é a maneira mais simples de fazê-lo. é uma maneira de simplesmente adicionar uma bandeira em sua tabela de algo (ativo / inativo com alguma restrição unicidade) e inserção na tabela de auditoria.

Outra maneira se você deseja que a tabela não armazenar os dados históricos é copiar o ex-linha na sua tabela de auditoria ...

Muitas pessoas têm muitas maneiras de fazê-lo. Mas uma coisa é certa, você terá que executar uma inserção para cada atualização / inserção / exclusão na tabela

Para evitar escrever a inserção na dúzia de lugares diferentes, você pode usar aqui um gatilho.

Eu concordo com todos aqui sobre restrições. Usá-los tanto quanto possível.

Há uma tendência para os gatilhos de uso excessivo, especialmente com novos desenvolvedores. Já vi situações em que um gatilho dispara outro gatilho que dispara outro gatilho que repete o primeiro gatilho, criando um gatilho em cascata que amarra seu servidor. Este é um utilizador não-óptima de gatilhos; o)

Dito isto, gatilhos têm o seu lugar e deve ser utilizado quando for apropriado. Eles são especialmente bons para rastrear alterações nos dados (como Mark Brackett mencionado). Você precisa responder a pergunta "Onde isso faz mais sentido colocar a minha lógica de negócios"? Na maioria das vezes eu acho que pertence ao código, mas você tem que manter a mente aberta.

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