2

我以前从未使用过触发器,但这似乎是一个可靠的用例。我想知道触发器是否是我应该使用的,如果是这样,我可以用一点手来了解如何去做。

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

我还没有需要在这两个表之间建立关系。INDEX我将单个用户的目标链接到主要目标,但只需按标题查询(在列上带有一个title)。现在我需要有一个关联这两个表的第三个表,但它只需要最终保持一致。会有两列,FOREIGN KEYsgoal_idusers_goal_id

触发器是解决这个问题的方法吗?如果是这样,那会是什么样子?

4

2 回答 2

1

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

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

首先是加入。你说一个goal有很多user goals。这是否意味着每个user goal人只属于一个人goal?如果是这样,您不需要额外的表。您可以在表格中添加一goal_iduser_goals。确保有一个外键约束(我希望你使用 InnoDB 表),这样你就可以强制引用完整性。

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

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

不,如果可以避免的话,你根本不应该使用触发器。

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

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

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

如果您可以摆脱它,只需在客户端编写一个通用例程,该例程总是被调用来更新共享列。

甚至触发器也无法确保列始终保持同步,因此您将需要实施一个定期过程来检查这一点。否则它们迟早会不同步(可能只是因为一些操作工程师决定开始手动更新;可能一个表从备份中恢复而另一个没有)

于 2010-11-22T05:17:30.900 回答