我应该使用触发器连接两个相关但严重非规范化的表吗?

时间:2010-11-21 21:47:21

标签: mysql triggers denormalization

我之前从未使用过触发器,但这似乎是一个坚实的用例。我想知道触发器是否应该是我应该使用的,如果是这样的话,我可以稍微用一下如何处理它。

基本上我有两个严重非规范化的表goalsusers_goals。两者都有title列(VARCHAR)复制title数据。因此,将有一个主要目标“学习如何使用触发器”,以及许多(在这种情况下可能并不多)用户的目标具有相同的标题。该网站的架构要求就是这种情况。

我还没有必要在这两个表之间建立关系。我将各个用户的目标与主要目标相关联,但只需按标题查询(INDEX列上有title)即可。 现在我需要有一个与这两个表相关的第三个表,但它只需要最终一致。会有两列,FOREIGN KEY s,goal_idusers_goal_id

触发器是否可以采用此方法?如果是这样,那会是什么样的?

2 个答案:

答案 0 :(得分:1)

是的,您可以使用触发器执行此操作,但具体实现取决于您的要求。

如果你想重建你的查询,所以他们不使用联接的标题,而是使用goal_id,你可以建立它。如果您还需要保持标题同步,这是一个额外的。

首先加入。您声明一个goal有很多user goals。这是否意味着每个user goal只属于一个goal?如果是这样,您不需要额外的表格。您只需在goal_id表格中添加一列user_goals即可。确保存在外键约束(我希望您使用的是InnoDB表),因此您可以强制执行参照完整性。

然后是触发器。我不确定如何在MySQL上编写它们。我在Oracle上使用了很多触发器,但很少在MySQL上使用。无论如何,我建议你建立三个触发器:

  1. 更新goals表上的触发器。当标题被修改时,此触发器应更新相关的user_goals表。
  2. 更新user_goals表上的触发器。如果修改了user_goals.title,则此触发器应检查goals表中的标题是否与user_goals中的新标题不同。如果是这样,您有两种选择:
    1. 例外:不允许在user_goals子表中修改标题。
    2. 更新:允许更改标题。更新目标中的父记录。目标触发器将为您更新其他相关的user_goals。
    3. 您也可以通过更改触发器中的值来默默忽略更改,但这不是一个好主意。
  3. user_goals上插入触发器。最简单的选择是查询指定的goal_id的标题,并且不允许为标题插入另一个值。如果给出了标题,您可以选择更新goals
  4. 在目标上插入触发器。不需要这个。

答案 1 :(得分:1)

不,如果可以避免,就不应该使用触发器。

触发器对我来说是一种反模式;它们具有“在程序员的背后做事”的效果。

想象一下,如果应用程序的未来维护者需要做一些事情,如果他们不知道触发器(想象他们没有详细检查过您的数据库模式创建脚本),那么他们可能会花费很长时间来尝试弄清楚为什么会这样。

如果需要更新表的多个客户端代码,请考虑使用存储过程;在代码维护手册(和注释等)中记录这一点,以确保未来的开发人员也这样做。

如果你能逃脱它,只需在客户端编写一个公共例程,它总是被调用以更新共享列。

偶数触发器不会确保列始终保持同步,因此您需要实现定期检查此过程的过程。否则它们迟早会失去同步(可能只是因为某些操作工程师决定开始进行手动更新;可能一个表从备份中恢复而另一个表没有恢复)