Должен ли я использовать триггеры для соединения двух связанных, но сильно денормализованных таблиц? - PullRequest
2 голосов
/ 22 ноября 2010

Я никогда раньше не использовал триггеры, но это похоже на хороший пример использования.Я хотел бы знать, если триггеры - то, что я должен использовать, и если так, я мог бы использовать небольшую руку, чтобы узнать, как это сделать.

По существу У меня есть две сильно денормализованные таблицы, goals и users_goals.Оба имеют title столбцы (VARCHAR), которые дублируют данные title.Таким образом, будет одна главная цель «Узнайте, как использовать триггеры», и цели многих (ну, может быть, не многих в этом случае) пользователей с одинаковым названием.Архитектура сайта требует, чтобы это было так.

У меня пока не было необходимости иметь отношения между этими двумя таблицами.Я связываю цели отдельных пользователей с основными целями, но просто делаю это с помощью запроса по названию (с INDEX в столбце title). Теперь мне нужна третья таблица, которая связывает эти две таблицы , но она должна быть только , в конечном итоге согласованной .Там будет два столбца, оба FOREIGN KEY s, goal_id и users_goal_id.

Есть триггеры способ пойти с этим?И если да, то как бы это выглядело?

Ответы [ 2 ]

1 голос
/ 22 ноября 2010

Нет, вам никогда не следует использовать триггеры, если вы можете их избежать.

Триггеры - это анти-паттерн для меня;они имеют эффект «делать вещи за спиной программиста».

Представьте, что будущему сопровождающему вашего приложения нужно что-то делать, если он не знает о триггере (представьте, что он не проверял вашу схему базы данныхсоздание сценариев), тогда они могут потратить много времени, пытаясь понять, почему это происходит.

Если вам нужно иметь несколько фрагментов кода на стороне клиента, обновляющего таблицы, подумайте над тем, чтобы заставить их использоватьхранимая процедура;документируйте это в руководстве по обслуживанию кода (и комментариях и т. д.), чтобы гарантировать, что будущие разработчики сделают то же самое.

Если вам это удастся, просто напишите на стороне клиента общую подпрограмму, которая всегда вызывается для обновленияобщий столбец (столбцы).

Даже триггеры ничего не делают, чтобы гарантировать, что столбцы всегда синхронизированы, поэтому вам потребуется реализовать периодический процесс, который все равно проверяет это.В противном случае они рано или поздно выйдут из синхронизации (возможно, только потому, что какой-то инженер по эксплуатации решит начать обновление вручную; возможно, одна таблица будет восстановлена ​​из резервной копии, а другая - нет)

1 голос
/ 22 ноября 2010

Да, вы можете сделать это с помощью триггеров, но точная реализация зависит от ваших требований.

Если вы хотите перестроить все свои запросы, чтобы они не использовали заголовок для объединения, а вместо этого вместо 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. Обновление: разрешить изменение названия. Обновите родительскую запись в целях. Триггер для целей обновит для вас другие связанные пользовательские цели.
    3. Вы также можете молча игнорировать изменение, изменив значение обратно в триггере, но это не будет хорошей идеей.
  3. Вставить триггер на user_goals. Самый простой вариант - запросить заголовок указанного goal_id и не допустить вставки другого значения для заголовка. Вы можете обновить goals, если указан заголовок.
  4. Вставьте триггер на цели. В этом нет необходимости.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...