¿Usa disparadores o transacciones MySQL?

8

Quiero pedirle su opinión sobre el uso de disparadores o transacciones de MySQL en un sitio web.

En realidad tengo una paymenttabla de historial con - UserId | OperationId | Comment | Credits | Sign (debit or credit). Por lo tanto, cada operación de pago se inserta en esta tabla.

Sin embargo, llevará mucho tiempo calcular cada vez que el monto total del crédito del usuario cada vez que realice una acción. Así que pensé que tal vez sea una buena idea mantener el monto total del crédito para cada usuario en una profiletabla de usuarios .

Aquí está el problema. ¿Cómo puedo estar seguro de que el monto total del crédito de la profiletabla permanecerá sincronizado con las operaciones de la paymenttabla del historial?

Pensé usar 2 métodos:

  • MySQL disparadores o
  • transacciones codificadas en el código fuente

¿Cuál es más confiable? ¿Qué sucede si tengo una base de datos grande (más de 100.000 usuarios)?

¿Tienes alguna sugerencia para hacer esto?

El motor BD MySQL es InnoDB.

Ek Kosmos
fuente

Respuestas:

8

Sin duda, descartaría desencadenantes y me quedaría estrictamente con las transacciones.

Los disparadores son, por naturaleza, procedimientos almacenados. Sus acciones son prácticamente difíciles de revertir . Incluso si todas las tablas subyacentes son InnoDB, experimentará un volumen proporcional de bloqueos de fila compartidos e intermitencia molesta de bloqueos de fila exclusivos. Tal sería el caso si los activadores estuvieran manipulando tablas con INSERT y ACTUALIZACIONES estancadas para realizar MVCC de servicio pesado dentro de cada llamada a un activador .

Combine esto con el hecho de que los protocolos de validación de datos adecuados no están implementados en el lenguaje de procedimiento almacenado de MySQL . Está bien que Business Intelligence haya contenido en una base de datos siempre que el lenguaje de procedimiento almacenado pueda manejar un entorno transaccional . Como MySQL DBA, debo decir honestamente que ese no es el caso con MySQL. Oracle (PL / SQL), PostgreSQL (PL / pgSQL) y SQL Server (T-SQL) tienen esta ventaja sobre MySQL.

Con respecto a las transacciones, MySQL tiene InnoDB como su principal motor de almacenamiento compatible con ACID (motor de almacenamiento Deafult en MySQL 5.5). Tiene una excelente recuperación ante fallos y obedece los protocolos de cumplimiento de ACID.

Elegiría transacciones en lugar de disparadores cada vez.

RolandoMySQLDBA
fuente
3

Estoy de acuerdo con la evaluación de Rolando. La lógica de su negocio debe residir en su aplicación y debe realizar cambios en la base de datos transaccionalmente.

Escalar a 100,000 usuarios, por supuesto, depende de su aplicación y del tráfico de la base de datos que genera. Con MySQL bajo una gran carga de escritura transaccional, es posible que pronto se enfrente con la carga de fragmentar y / o replicar su conjunto de datos para mantener una respuesta de aplicación aceptable.

Sin embargo, hay alternativas a fragmentar MySQL. Uno de ellos es Clustrix (mi empleador), que es un sistema de base de datos SQL de instancia única de alto rendimiento escalable en paralelo. Es un sistema de base de datos en clúster que se presenta como un único servidor MySQL. Escalar la base de datos descrita en este hilo sin problemas a 100,000 usuarios en una sola instancia de Clustrix no requeriría fragmentación ni lógica de aplicación adicional.

blbryant
fuente
+1 para una buena respuesta y un enchufe descarado para Clustrix. Jajaja !!!
RolandoMySQLDBA
1

Buena respuesta de Rolando.

Además, los disparadores no deben usarse para la lógica, porque un par de disparadores interrelacionados más tarde, las cosas se volverán confusas rápidamente. Un buen conjunto de instrucciones en un procedimiento almacenado o en un procedimiento del lado del cliente puede transmitir la lógica empresarial con mayor claridad que un montón de lógica oculta en la base de datos. También hay limitaciones en los desencadenantes con respecto a la tabla desde la que se desencadenan, por lo que puede encontrarse dividiendo su lógica en dos lugares diferentes.

Además, puede encontrar formas de optimizar en qué momento estos cálculos suceden en su servidor de lógica de negocios, mientras que un disparador se disparará cada vez. Te encontrarás apagando el gatillo, actualizando la tabla y luego volviendo a habilitar el gatillo, lo que también significa que debes poner la lógica del gatillo en ese código.

Además, no es necesario que tenga toda la lógica en la parte de lógica de negocios del código, es posible que desee aplicar la integridad de la tabla mediante el uso de procedimientos almacenados. Esto puede iniciar una transacción, realizar múltiples actualizaciones y hacer que las cosas retrocedan muy bien si algo falla. De esa manera, alguien que mira la base de datos puede ver la lógica para insertar un pedido, por ejemplo. Esto es menos importante en el mundo actual, ya que los servicios web pueden ser la interfaz de acceso único a la base de datos; pero en el caso de que varios ejecutables tengan acceso a la base de datos, esto puede ser enorme.

Además, de todas formas tendrá transacciones, no ejecutará sus disparadores sin uno ... ¿verdad? Por lo tanto, es bueno saber cómo iniciar una transacción; hacer algunas cosas y luego finalizar una transacción. Si ve este patrón en su código, una pieza más de código que lo use será ligero en la carga cognitiva. Un disparador, si recuerda que está allí, lo obligará a pensar de manera diferente para aquellas transacciones que se ven afectadas por el disparador, especialmente si se extraen otras tablas que también pueden tener disparadores.

Básicamente, entre un trabajo cron programado regularmente (o trabajo de agente de base de datos) y buenos procedimientos almacenados, puede lograr el 99% de lo que desea. El 1%; repensar el proyecto.

Gerard ONeill
fuente
En conclusión, ¿su consejo sería inequívocamente NUNCA UTILIZAR UN DISPARADOR en una aplicación seria con lógica comercial?
Ifedi Okonkwo
En general si. Puedo ver situaciones en las que tienes disparadores para realizar validaciones extrañas, quizás de múltiples filas. También puedo ver que se usan para generar indicadores de 'hechos', tal vez esto es solo una forma de validación donde el resultado de la validación se almacena en algún lugar. Puedo ver que se usan para actualizaciones de información de la tabla (una bandera o una tabla que indica qué filas han cambiado, por ejemplo). Sin embargo, no importa cuán simples y limpias sean estas implementaciones, prefiero que esto se haga en un procedimiento almacenado o en una API db (es decir, el modelo).
Gerard ONeill