У меня есть несколько таблиц в базе данных SQL, и я хочу иметь еще одну таблицу (скажем, Stats
), которая будет содержать некоторую статистику по этим таблицам (средние значения, счетчики и т. д.)
Я мог бы обновлять X каждый раз, когда изменяется одна из моих таблиц, например:
INSERT INTO Things VALUES (x, y, z);
UPDATE Stats
SET AverageX = (SELECT avg(x) FROM Things WHERE Things.y = "identifier")
WHERE Stats.y = "identifier";
Но это кажется неэффективным (каждый раз с усреднением). Более того, возможно, что Stats
не будет содержать запись, которая соответствует Stats.y = "identifier"
, поэтому мне может потребоваться проверить это и, возможно, сначала создать запись.
Итак, вопрос: как порядочные люди делают такие вещи?
Какой СУБД вы используете? «SQL» - это просто язык запросов, а не имя конкретного продукта базы данных. Добавьте тег для продукта базы данных, который вы используете postgresql
, oracle
, sql-server
, db2
, ...
В T-SQL (sql-server) для сумм и подсчетов могут использоваться индексированные представления; для минимумов и максимумов, к сожалению, нет.
Это слишком долго для комментария.
Вы можете сделать это автоматически, установив триггеры (вставка, удаление и обновление) для всех таблиц, в которых вы храните данные. Вероятно, вы не захотите хранить среднее значение в таблице статистики. Вместо этого вам нужна сумма и подсчет.
Однако делать это следует только при соблюдении следующих условий:
Если эти условия не выполняются и ваши таблицы относительно малы, может быть достаточно представления, которое вычисляет статистику на лету.
Обратите внимание, что некоторые статистические данные можно очень быстро вычислить с помощью индексов - в частности, MIN()
и MAX()
.
Поддержание триггеров нетривиально. А поддерживать согласованность в разных таблицах сложно (рассмотрим bulk insert
или truncate table
, которые не выполняют триггеры).
Какая цель? Используйте триггеры.