Лучший способ еженедельного обновления поля MYSQL? - PullRequest
1 голос
/ 21 октября 2019

Я хочу еженедельно обновлять поле в таблице MySQL «Персоны», используя среднее из двух полей таблицы «Задачи»: end_date и start_date:

PERSON:
+----------------+-------------+------+-----+---------+-------+
| Field          | Type        | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| average_speed  | int(11)     | NO   |     | 0       |       |
+----------------+-------------+------+-----+---------+-------+

TASKS:
+----------------+-------------+------+-----+---------+-------+
| Field          | Type        | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| person_id      | int(11)     | NO   |     | NULL    |       |
| start_date     | date        | NO   |     | NULL    |       |
| end_date       | date        | NO   |     | NULL    |       |
+----------------+-------------+------+-----+---------+-------+

(таблицы не заполнены).

average_speed = AVG (task.end_date - task.start_date)

Теперь таблица Tasks действительно велика, и ** Я не хочу вычислять среднее значение для каждой задачи длякаждый человек каждую неделю **. (Это решение, но я стараюсь его избегать).

Какой лучший способ обновить среднюю скорость? Я думал о добавлении двух столбцов в таблицу этого человека:

  • "last_count": количество вычисленных задач с тех пор, как теперь для каждого человека
  • "last_sum": последняя сумма (end_date - start_date) для каждого человека

Чтобы в новом обновлении я мог сделать что-то вроде average_speed = (last_sum + new_sum) / (last_count + new_count), где new_count - сумма задач за последнюю неделю.

Есть ли лучшее решение / архитектура?

РЕДАКТИРОВАТЬ: чтобы ответить на комментарий, запрос, который я бы сделал, выглядит примерно так:

SELECT 
    count(t.id) as last_count,
    sum(TIMESTAMPDIFF(MINUTE, t.start_date, t.end_date)) as last_sum
    avg(TIMESTAMPDIFF(MINUTE, t.start_date, t.end_date))
from tasks as t
where t.end_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 1 WEEK) AND CURDATE()

И я могу положиться на php-скрипт, чтобы получить результат и сделать некоторые вычисления

1 Ответ

1 голос
/ 22 октября 2019

Периодическое обновление таблицы - это плохой способ пойти по всем причинам, перечисленным выше и т. Д.

Если у вас есть доступ к коду, который записывает в таблицу задач, этолучшее место, чтобы поставить обновление. Добавьте поле Среднее, вычислите и установите значение при записи времени окончания задачи.

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

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

...