开发者

Should I be using triggers to connect two related but heavily denormalized tables?

开发者 https://www.devze.com 2023-01-26 19:08 出处:网络
I\'ve never used triggers before, but this seems like a solid use case. I\'d like to know if triggers are what I should be using, and if so, I could use a little hand-holding on how to go 开发者_开发技

I've never used triggers before, but this seems like a solid use case. I'd like to know if triggers are what I should be using, and if so, I could use a little hand-holding on how to go 开发者_开发技巧about it.

Essentially I have two heavily denormalized tables, goals and users_goals. Both have title columns (VARCHAR) that duplicate the title data. Thus, there will be one main goal of "Learn how to use triggers", and many (well, maybe not many in this case) users' goals with the same title. The architecture of the site demands that this be the case.

I haven't had a need to have a relationship between these two tables just yet. I link from individual users' goals to the main goals, but simply do so with a query by title, (with an INDEX on the title column). Now I need to have a third table that relates these two tables, but it only needs to be eventually consistent. There would be two columns, both FOREIGN KEYs, goal_id and users_goal_id.

Are triggers the way to go with this? And if so, what would that look like?


Yes you could do this using triggers, but the exact implementation depends on your demands.

If you want to rebuild al your queries, so they don't use the title for the join, but the goal_id instead, you can just build that. If you need to keep the titles in sync as well, that's an extra.

First for the join. You stated that one goal has many user goals. Does that mean that each user goal belongs to only one goal? If so, you don't need the extra table. You can just add a column goal_id to your user_goals table. Make sure there is a foreign key constraint (I hope you're using InnoDB tables), so you can enforce referential integrity.

Then the trigger. I'm not exactly sure how to write them on MySQL. I do use triggers a lot on Oracle, but only seldom on MySQL. Anyway, I'd suggest you build three triggers:

  1. Update trigger on goals table. This trigger should update related user_goals table when the title is modified.
  2. Update trigger on the user_goals table. If user_goals.title is modified, this trigger should check if the title in the goals table differs from the new title in user_goals. If so, you have two options:
    1. Exception: Don't allow the title to be modified in the user_goals child table.
    2. Update: Allow the title to be changed. Update the parent record in goals. The trigger on goals will update the other related user_goals for you.
    3. You could also silently ignore the change by changing the value back in the trigger, but that wouldn't be a good idea.
  3. Insert trigger on user_goals. Easiest option is to query the title of the specified goal_id and don't allow inserting another value for title. You could opt to update goals if a title is given.
  4. Insert trigger on goals. No need for this one.


No, you should never use triggers at all if you can avoid it.

Triggers are an anti-pattern to me; they have the effect of "doing stuff behind the programmer's back".

Imagine a future maintainer of your application needs to do something, if they are not aware of the trigger (imagine they haven't checked your database schema creation scripts in detail), then they could spend a long, long time trying to work out why this happens.

If you need to have several pieces of client-side code updating the tables, consider making them use a stored procedure; document this in the code maintenance manual (and comments etc) to ensure that future developers do the same.

If you can get away with it, just write a common routine on the client side which is always called to update the shared column(s).

Even triggers do nothing to ensure that the columns are always in sync, so you will need to implement a periodic process which checks this anyway. They will otherwise go out of sync sooner or later (maybe just because some operations engineer decides to start doing manual updates; maybe one table gets restored from a backup and the other doesn't)

0

精彩评论

暂无评论...
验证码 换一张
取 消