Как проверить согласованность таблиц при помощи хранимой процедуры?

Марк

Доброго времени суток :)

Есть некоторая БД, в которой существуют две таблицы: сотрудник и отдел. В таблице сотрудник хранится информация о сотруднике, что логично, а в таблице отдел, помимо еще кучи полей, есть поле, в котором указано количество сотрудников какого-либо отдела. Заданием является написание триггера, который вносит изменение в поле "Количество сотрудников" после добавление нового сотрудника в таблицу "Сотрудники". Если коротко, то: добавил сотрудника, с помощью триггера увеличь на 1 кол-во сотрудников в другой таблице. И появился такой нюанс, если изначально таблицы рассогласованна ( в таблице "Сотрудники" 20 человек из отдела X, а в таблице "Отдел" в поле количество сотрудников их всего, например, 6), то как, при помощи хранимой процедуры согласовать таблицы? Иначе триггеры смысла не имеют, ваш Кэп.

Спасибо за внимание :)

1 ответ

Марк

В указанной задаче написание триггера или процедуры приносит проблемы согласованности и лишние сущности для базы данных без логического обоснования данного решения.

Хранить агрегированное количество требуется только там, где запрос на выборку занимает продолжительное время. Например, финансовая история и общий баланс по кошельку на основе этой истории. Пару миллионов операций и расчет баланса может превратиться в длительное ожидание, а баланс пользователю надо было показать еще вчера.

Если требуется получить количество сотрудников в отделе, делайте это запросом, примерно следующим:

SELECT departament.name, COUNT(*)
FROM departament
JOIN staff ON staff.departament_id = departament.id 
GROUP BY departament.id

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

UPDATE к комментарию

Тогда запрос еще проще:

UPDATE departament
SET count =
  (SELECT COUNT(*)
   FROM staff
   WHERE departament_id=departament.id)

А вот процедура:

DELIMITER //  

CREATE PROCEDURE `correct_count`()  
BEGIN  
         UPDATE departament
SET count =
  (SELECT COUNT(*)
   FROM staff
   WHERE departament_id=departament.id)
END//

sqlFiddle

licensed under cc by-sa 3.0 with attribution.