Сохранение и вычисление совокупных значений

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

Например, предположим, что у меня есть виджеты, которые пользователи могут оценивать (см. схему ниже). Каждый раз, когда я показываю виджет, я мог бы рассчитать средний рейтинг пользователей из таблицы Ratings. В качестве альтернативы я мог бы сохранить средний рейтинг в таблице Widget. Это избавило бы меня от необходимости рассчитывать рейтинг каждый раз, когда я показываю виджет, но тогда мне придется пересчитывать средний рейтинг каждый раз, когда пользователь оценивает виджет.

Ratings       Widgets
---------     -------
widget_id     widget_id
user_id       name              
rating        avg_rating  <--- The column in question
84 голоса | спросил BenV 5 Jam1000000amWed, 05 Jan 2011 04:32:11 +030011 2011, 04:32:11

4 ответа


52

Это зависит. Предварительное вычисление совокупных значений создает большую нагрузку на записи, и их получение затрудняет чтение [

Если вы часто обращаетесь к производному значению, предварительный расчет является действительным этапом де-нормализации. Однако в этом случае я рекомендую использовать Materialized View (представление, записанное на диск, связанное триггером с родительскими таблицами). Материализованное представление предназначено для хранения часто задаваемых, но утомительных данных, и полезно для большого количества записей и низкого количества чтений.

В сценарии с высоким уровнем записи, с высоким уровнем чтения, рассмотрите задачу в фоновом режиме, которая имитирует эффекты материализованного представления, но меньше, чем в реальном времени. Это будет показывать «достаточно хорошее» среднее значение при сохранении производительности записи и чтения.

Ни в коем случае не следует обрабатывать производный столбец как «обычный» столбец: убедитесь, что данные, представленные в представлении «Виджеты», присутствуют в другом месте таблицы, так что весь кортеж может быть получен любыми процессами, которые вы устанавливать. Этот вопрос также сильно зависит от базы данных (и базы данных), поэтому я рекомендую тестирование производительности агрегата (с соответствующими индексами) с набором данных нормального размера и материализованным представлением.

ответил Brian Ballsun-Stanton 5 Jam1000000amWed, 05 Jan 2011 04:44:35 +030011 2011, 04:44:35
10

Как часто вам нужно вычислять /отображать значения относительно того, как часто изменяются /обновляются базовые номера.

Итак, если у вас есть сайт с ежедневными хитами 10k, которые отображают значение, которое будет меняться только один раз в час, я бы вычислил его при изменении базовых значений (может быть триггер базы данных, что угодно).

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

ответил Joe 5 Jam1000000amWed, 05 Jan 2011 04:44:04 +030011 2011, 04:44:04
4

Используйте таблицу StaleWidgets как очередь «недопустимых» (для пересчета) виджетов. Используйте другую задачу (асинхронную), которая может пересчитать эти значения. Период или момент пересчета зависит от системных требований:

  • только что прочитанный,
  • в конце месяца,
  • для некоторых пользователей в начале дня
  • ...
ответил garik 5 Jam1000000amWed, 05 Jan 2011 09:46:48 +030011 2011, 09:46:48
2

Я бы посоветовал сделать вывод о том, что калорация не слишком громоздка, и если у вас сложная калькуляция и частое обновление, но не чтение frequnet, чем вы можете хранить вычисленные данные и иметь дополнительный столбец (bool), который будет хранить, будет ли пересчет требуется или нет. например установите для этого столбца значение true, когда необходимо произвести перерасчет, но не выполнять перерасчет, а когда вы выполняете перерасчет, установите этот столбец как false (это будет отображаемое значение является последним и не устарело).

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

ответил techExplorer 11 52011vEurope/Moscow11bEurope/MoscowFri, 11 Nov 2011 10:29:59 +0400 2011, 10:29:59

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132