使用MySQL触发器或事务?


8

我想问一下您在网站上使用MySQL触发器或事务的意见。

实际上,我有一个payment带有- 的历史记录表UserId | OperationId | Comment | Credits | Sign (debit or credit)。因此,每个付款操作都会插入此表中。

但是,计算用户每次执行操作时的总信用额度将非常耗时。因此,我认为将每个用户的总信用额保留在用户profile表中可能是一个好主意。

这是问题所在。如何确定表格中的总贷方金额profilepayment历史记录表格中的操作保持同步?

我认为使用2种方法:

  • MySQL触发器或
  • 源代码中编码的交易

哪个更可靠?如果我有大型数据库(超过100.000个用户)怎么办?

您对此有何建议?

BD MySQL引擎是InnoDB。

Answers:


8

毫无疑问,我会排除触发器,并严格遵守交易。

触发器本质上是存储过程。他们的行动实际上很难退缩。即使所有基础表都是InnoDB,您也会遇到一定比例的共享行锁,并且排他行锁会产生令人讨厌的间歇性。如果触发器正在处理表而INSERT和UPDATE被停滞以在每次对触发器的调用内执行重型MVCC,则将是这种情况。

结合使用MySQL的存储过程语言未实现正确的数据验证协议这一事实。只要存储过程语言可以处理事务环境,就可以将Business Intelligence包含在数据库中。作为MySQL DBA,我必须老实地说,MySQL并非如此。Oracle(PL / SQL),PostgreSQL(PL / pgSQL)和SQL Server(T-SQL)在MySQL方面具有优势。

关于事务,MySQL将InnoDB作为其主要的ACID兼容存储引擎(MySQL 5.5中的默认存储引擎)。它具有出色的崩溃恢复功能,并遵守ACID遵从协议。

我会每次都选择transacitons而不是触发器。


3

我同意罗兰多的评估。您的业​​务逻辑应驻留在您的应用程序中,并应以事务方式更改数据库。

当然,扩展到100,000个用户取决于您的应用程序及其生成的数据库流量。在MySQL承受巨大的事务写负载的情况下,您可能很快会面临分片和/或复制数据集的负担,以维持可接受的应用程序响应。

但是,还有分片MySQL的替代方法。其中之一是Clustrix(我的雇主),它是一个可并行扩展的高性能单实例SQL数据库系统。它是一个集群数据库系统,将其表现为单个MySQL服务器。在单个Clustrix实例上,将该线程中描述的数据库无缝扩展到100,000个用户将不需要分片,也不需要其他应用程序逻辑。


+1表示良好答案,Clustrix则使用了无耻的插头。大声笑 !!!
RolandoMySQLDBA 2011年

1

罗兰多的好答案。

另外-触发器不应该用于逻辑,因为稍后会有几个相互关联的触发器,事情很快就会变得混乱。与数据库中的一堆隐藏逻辑相比,存储过程或客户端过程中的一组不错的指令可以更清楚地了解业务逻辑。关于触发器从中触发的表,也有一些限制-因此您可能会发现自己将逻辑拆分到两个不同的位置。

另外,您可能会找到优化这些计算在业务逻辑服务器中发生的时间的方式,而触发器将每次触发一次。您会发现自己关闭了触发器,更新了表,然后重新启用了触发器-这也意味着您需要将触发器逻辑放入代码中。

另外-您不必在代码的业务逻辑部分中包含所有逻辑-您可能想通过使用存储过程来增强表的完整性。这样可以启动事务,进行多次更新,并在发生某些故障时使它们回滚。这样,例如,查看数据库的人可以看到插入订单的逻辑。由于Web服务可以是对db的单一访问接口,因此在当今世界中这并不重要。但是在多个可执行文件可以访问数据库的情况下,这可能会很大。

另外-无论如何您都会进行交易-如果没有一个交易您就不会执行触发器...对吗?因此,很高兴知道如何开始交易。做一些事情;然后结束交易。如果您在代码中看到此模式,那么使用该模式的另一段代码将减轻认知负担。触发器(如果您记得它在那里)将迫使您对受触发器影响的那些事务进行不同的思考,尤其是如果拉入其他表也可能具有触发器。

基本上,在定期计划的cron作业(或数据库代理作业)和良好的存储过程之间,您可以完成99%的目标。1%;重新考虑项目。


总之,您的建议无疑是在具有业务逻辑的严肃应用程序中不要使用触发器?
Ifedi Okonkwo 2015年

一般来说,是的。我可以看到您有触发执行奇怪的(也许是多行)验证的情况。我还可以看到它们被用来生成“事实”标志-也许这只是一种验证形式,其中验证结果存储在某个地方。我可以看到它们用于表信息更新(例如,标志或表指示哪些行已更改)。但是,无论这些实现多么简单和干净,我都希望在存储过程或db api(即模型)中完成这些工作。
Gerard ONeill
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.