【问题标题】:When to use stored procedures and triggers vs the applicative layer何时使用存储过程和触发器与应用层
【发布时间】:2013-05-10 18:55:20
【问题描述】:

我有一个两难的问题,希望你能有一些专家意见。

我有一个名为 CARDS 的表,其中有一列 STATUS。如果记录的状态从“下载”变为“发布”,我必须将记录引用插入到另一个名为 CARD_ASSIGNMENTS 的表中。此外,需要将记录添加到 CARD_ASSIGNMENTS 中的次数与 SCANNERS 中的活动记录一样多。

换句话说,如果有两个活动的扫描仪,我将在 CARD_ASSIGNMENTS 中得到两条记录,如下所示:

ID   CARD_ID   SCANNER_ID   STATUS_ID
1    1         1            4
2    1         2            4

我的困境是我不太确定执行上述操作的最有效方法是什么。我考虑了以下选项:

  1. 从 PHP - 执行一个 UPDATE 查询,然后执行 INSERT 查询。
  2. 创建一个存储过程,它将负责更新 CARDS 记录并将记录添加到 CARD_ASSIGNMENTS 中。然后,只需从 PHP 调用该存储过程。
  3. 为 CARDS 表创建一个 ON UPDATE 触发器,该触发器将负责将 INSERTS 处理到 CARD_ASSIGNMENTS 表中。

附言。我的数据库的简化版本可在 MySQL Fiddle

上找到

谢谢,
凯特

【问题讨论】:

  • 我稍微更改了您的标题以反映困境。如果你更喜欢它之前的样子,你可以完美地把它转回来。

标签: php mysql database-design


【解决方案1】:

有趣的问题。

我将为您提供有关如何解决问题的线索。

因此,您必须从准确定义三件事开始:

  1. 预期的功能
  2. 功能的访问策略
  3. 技术升级政策

这里我将详细说明这些点。

所以,第一点是你必须定义你的功能。通过这样做,您将能够判断添加卡片是否意味着总是,在您的信息系统的所有可能范式(抱歉,我找不到更合适的迂腐词)中,根据您提供的规范,此卡必须存在于另一个表中。这个 1-1 功能链接必须说 TRUE 或 FALSE。这真的很重要。 换句话说,如果至少有一种可能性是有一天您不想将该记录复制到另一张表中,则意味着触发器是错误的解决方案,或者至少应该考虑使用紧急模式(对于例如内部的一个变量,允许它在某些条件下不被执行)设置。

然后是第二点,关于访问策略。您必须知道允许的访问系统是否会通过使用您的 应用程序层来执行此操作,或者他们是否可以开发自己的(SAAS 样式)。如果是这样,您的 php 层将毫无用处,而存储过程是一个很好的选择,因为每个技术和业务层都会通过它是或是。

最后要知道的是你是否有可能有一天会升级你的 php 层。在大多数情况下,答案是肯定的。如果是这样,您可能必须修改包含您正在谈论的此 sql 逻辑的部分。然后,将所有内容都存储到存储过程中而不是将其硬编码到 php 中,肯定会节省您的时间,并提高稳定性。


左脑右脑,我还是说说我个人的看法吧。我真的很喜欢使用存储过程,但不使用任何触发器。如果环境允许,我会选择底层批处理,调用一组已定义的存储过程,将活动集中在在线范围之外。

优点如下:

  • 由于您减少了操作次数,因此在线工作流程中断的风险不会或更少
  • 减轻数据库负载的不同计划
  • 更安全的策略,因为执行存储过程只需要一个授权,而使用与 php 相同的 sql 则需要插入/更新授权
  • 更好的日志记录质量:您可以为每个作业创建一个日志
  • 更好的应急响应:当作业失败时(如果经过深思熟虑),您可以重新启动它,仅此而已。

很长的帖子,但这很有趣,我真的很想分享这些想法。

干杯!

【讨论】:

  • 我同意,存储过程是 9/10 倍的路要走。触发器过于“隐藏”,因此它们很容易产生难以解决的问题,而且 Web 代码变化多端且不可移植
  • Sebas,感谢您的认可 ;) 考虑到您概述的要点,我将采用存储过程路线,因为您的很多观点都一针见血。此外,我实际上从未使用过触发器,所以我很犹豫选择那条路线。由于我正在使用一个高流量的网站,因此我对性能也很偏执,并且逻辑表明我必须从 PHP 进行的调用越少越好。再次感谢您的意见,非常感谢。
  • 不客气。关于性能,通常在数据库层做得越多越快。
【解决方案2】:

我会使用触发器。一些开发人员说,如果你有太多的触发器和存储过程,数据库就会过着自己的生活,这意味着你永远不知道插入、更新等会发生什么。但在我看来,触发器可能对你有很大帮助保持数据库一致,因此即使有人直接从某个管理工具插入数据,仍然保持完整性,因为所有必要的命令都已执行。如果您选择存储过程,您仍然必须知道,您需要调用此过程来插入任何新数据。

【讨论】:

  • 嗯,非常有效的观点。您对触发器如何影响 MySQL 的性能有任何想法吗?我正在一个非常繁忙的服务器上工作,并且由于触发器在每次更新时都会触发,这不会影响性能,考虑到这个触发器实际上只会在非常特定的条件下运行(当状态从“下载”更改时) '验证')。
猜你喜欢
  • 2013-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多