我之前从未使用过触发器,但这似乎是一个坚实的用例。我想知道触发器是否应该是我应该使用的,如果是这样的话,我可以稍微用一下如何处理它。
基本上我有两个严重非规范化的表,goals
和users_goals
。两者都有title
列(VARCHAR
)复制title
数据。因此,将有一个主要目标“学习如何使用触发器”,以及许多(在这种情况下可能并不多)用户的目标具有相同的标题。该网站的架构要求就是这种情况。
我还没有必要在这两个表之间建立关系。我将各个用户的目标与主要目标相关联,但只需按标题查询(INDEX
列上有title
)即可。 现在我需要有一个与这两个表相关的第三个表,但它只需要最终一致。会有两列,FOREIGN KEY
s,goal_id
和users_goal_id
。
触发器是否可以采用此方法?如果是这样,那会是什么样的?
答案 0 :(得分:1)
是的,您可以使用触发器执行此操作,但具体实现取决于您的要求。
如果你想重建你的查询,所以他们不使用联接的标题,而是使用goal_id,你可以建立它。如果您还需要保持标题同步,这是一个额外的。
首先加入。您声明一个goal
有很多user goals
。这是否意味着每个user goal
只属于一个goal
?如果是这样,您不需要额外的表格。您只需在goal_id
表格中添加一列user_goals
即可。确保存在外键约束(我希望您使用的是InnoDB表),因此您可以强制执行参照完整性。
然后是触发器。我不确定如何在MySQL上编写它们。我在Oracle上使用了很多触发器,但很少在MySQL上使用。无论如何,我建议你建立三个触发器:
goals
表上的触发器。当标题被修改时,此触发器应更新相关的user_goals
表。user_goals
表上的触发器。如果修改了user_goals.title
,则此触发器应检查goals
表中的标题是否与user_goals
中的新标题不同。如果是这样,您有两种选择:
user_goals
上插入触发器。最简单的选择是查询指定的goal_id
的标题,并且不允许为标题插入另一个值。如果给出了标题,您可以选择更新goals
。答案 1 :(得分:1)
不,如果可以避免,就不应该使用触发器。
触发器对我来说是一种反模式;它们具有“在程序员的背后做事”的效果。
想象一下,如果应用程序的未来维护者需要做一些事情,如果他们不知道触发器(想象他们没有详细检查过您的数据库模式创建脚本),那么他们可能会花费很长时间来尝试弄清楚为什么会这样。
如果需要更新表的多个客户端代码,请考虑使用存储过程;在代码维护手册(和注释等)中记录这一点,以确保未来的开发人员也这样做。
如果你能逃脱它,只需在客户端编写一个公共例程,它总是被调用以更新共享列。
偶数触发器不会确保列始终保持同步,因此您需要实现定期检查此过程的过程。否则它们迟早会失去同步(可能只是因为某些操作工程师决定开始进行手动更新;可能一个表从备份中恢复而另一个表没有恢复)