Usando gatilhos ou transações MySQL?

8

Quero perguntar sua opinião sobre o uso de gatilhos ou transações do MySQL em um site.

Na verdade, eu tenho uma paymenttabela de histórico com - UserId | OperationId | Comment | Credits | Sign (debit or credit). Portanto, cada operação de pagamento é inserida nesta tabela.

No entanto, será demorado calcular cada vez que o valor total do crédito do usuário toda vez que ele executar uma ação. Por isso, pensei que talvez seja uma boa ideia manter o valor total do crédito para cada usuário em uma profiletabela de usuários .

Aqui está o problema. Como posso ter certeza de que o valor total do crédito da profiletabela permanecerá sincronizado com as operações da paymenttabela de histórico?

Eu pensei usando 2 métodos:

  • O MySQL dispara ou
  • transações codificadas no código fonte

Qual é mais confiável? E se eu tiver um banco de dados grande (mais de 100.000 usuários)?

Você tem alguma sugestão para fazer isso?

O mecanismo BD MySQL é o InnoDB.

Ek Kosmos
fonte

Respostas:

8

Sem dúvida, descartaria gatilhos e ficaria estritamente com as transações.

Os gatilhos são, por natureza, procedimentos armazenados. Suas ações são praticamente difíceis de reverter . Mesmo que todas as tabelas subjacentes sejam o InnoDB, você experimentará um volume proporcional de bloqueios de linha compartilhados e intermitência irritante dos bloqueios de linha exclusivos. Esse seria o caso se os gatilhos estivessem manipulando tabelas com INSERTs e UPDATEs estagnados para executar MVCC pesado dentro de cada chamada para um gatilho .

Combine isso com o fato de que os protocolos de validação de dados adequados não são implementados na Stored Procedure Language do MySQL . É bom que o Business Intelligence contenha um banco de dados, desde que o Stored Procedure Language possa lidar com um ambiente transacional . Como DBA do MySQL, devo dizer honestamente que esse não é o caso do MySQL. Oracle (PL / SQL), PostgreSQL (PL / pgSQL) e SQL Server (T-SQL) têm essa vantagem sobre o MySQL.

Em relação às transações, o MySQL tem o InnoDB como seu principal mecanismo de armazenamento compatível com ACID (mecanismo de armazenamento Deafult no MySQL 5.5). Possui excelente recuperação de falhas e obedece aos protocolos de conformidade com o ACID.

Eu escolheria transacitons em vez de gatilhos toda vez.

RolandoMySQLDBA
fonte
3

Eu concordo com a avaliação de Rolando. Sua lógica de negócios deve residir no seu aplicativo e deve fazer alterações no banco de dados de maneira transacional.

A expansão para 100.000 usuários, é claro, depende do seu aplicativo e do tráfego do banco de dados que ele gera. Com o MySQL sob uma carga de gravação transacional pesada, você pode se deparar com os encargos de fragmentar e / ou replicar seu conjunto de dados para manter uma resposta aceitável do aplicativo.

No entanto, existem alternativas para fragmentar o MySQL. Um deles é o Clustrix (meu empregador), que é um sistema de banco de dados SQL de instância única e alto desempenho escalonável em paralelo. É um sistema de banco de dados clusterizado que se apresenta como um único servidor MySQL. O dimensionamento do banco de dados descrito neste encadeamento para 100.000 usuários em uma única instância do Clustrix não exigiria sharding nem lógica de aplicativo adicional.

brilhante
fonte
+1 para uma boa resposta e plugue descarado para o Clustrix. RI MUITO !!!
RolandoMySQLDBA
1

Boa resposta de Rolando.

Além disso - os gatilhos não devem ser usados ​​para a lógica, porque alguns gatilhos inter-relacionados posteriormente, as coisas ficam confusas rapidamente. Um bom conjunto de instruções em um procedimento armazenado ou no lado do cliente pode atravessar a lógica de negócios mais claramente do que um monte de lógica oculta no banco de dados. Também existem limitações nos gatilhos em relação à tabela da qual eles são acionados - portanto, você pode se dividir em dois lugares diferentes.

Além disso, você pode encontrar maneiras de otimizar em que ponto esses cálculos acontecem no servidor de lógica de negócios, enquanto um gatilho será acionado toda vez. Você se verá desligando o gatilho, atualizando a tabela e reativando o gatilho - o que também significa que é necessário colocar a lógica do gatilho nesse código.

Além disso - você não precisa ter toda a lógica na parte da lógica de negócios do código - poderá impor a integridade da tabela usando procedimentos armazenados. Isso pode iniciar uma transação, fazer várias atualizações e fazer com que as coisas retornem bem se algo falhar. Dessa forma, alguém olhando para o banco de dados pode ver a lógica para inserir um pedido, por exemplo. Isso é menos importante no mundo de hoje, pois os serviços da web podem ser a interface de acesso único ao banco de dados; mas no caso de vários executáveis ​​terem acesso ao banco de dados, isso pode ser enorme.

Além disso - você terá transações de qualquer maneira - não executará seus gatilhos sem um ... certo? Portanto, é bom saber como iniciar uma transação; faça algumas coisas; e finalize uma transação. Se você vir esse padrão em seu código, mais um trecho de código que será usado será leve na carga cognitiva. Um gatilho, se você se lembrar de que está lá, forçará você a pensar de maneira diferente nas transações afetadas pelo gatilho, especialmente se outras tabelas forem recebidas e que também possam ter gatilhos.

Basicamente, entre um trabalho cron agendado regularmente (ou trabalho do agente de banco de dados) e bons procedimentos armazenados, você pode realizar 99% do que deseja. O 1%; repensar o projeto.

Gerard ONeill
fonte
Em conclusão, seu conselho seria inequivocamente NUNCA USAR UM GATILHO em um aplicativo sério com lógica de negócios?
Ifedi Okonkwo
Em geral, sim. Eu posso ver situações em que você tem gatilhos para realizar validações estranhas, talvez com várias linhas. Também posso vê-los sendo usados ​​para gerar sinalizadores de 'fatos' - talvez seja apenas uma forma de vaidação em que o resultado da validação esteja armazenado em algum lugar. Eu posso vê-los sendo usados ​​para atualizações de informações da tabela (um sinalizador ou uma tabela que indica quais linhas foram alteradas, por exemplo). No entanto, não importa quão simples e limpas essas implementações sejam, eu prefiro que essas coisas sejam feitas em um procedimento armazenado ou em uma API de banco de dados (por exemplo, o modelo).
Gerard ONeill