Я разрабатываю проект на работе, для которого мне нужно создать и поддерживать Сводные таблицы по соображениям производительности. Я считаю, что правильным термином для этого является Материализованные виды.Предпочтительный метод для материализованных представлений (сводные таблицы) с MySQL
У меня есть 2 основные причины, чтобы сделать это:
Денормализация
я нормализовал таблицы как можно больше. Таким образом, есть ситуации, когда мне придется объединять многие таблицы, чтобы извлекать данные. Мы работаем с MySQL Cluster, который имеет довольно низкую производительность, когда дело доходит до JOIN.
Так что мне нужно создать Denormalized Tables, который может работать быстрее SELECT.
Обобщить данные
К примеру, у меня есть таблица сделок с несколько миллионов записей. Сделки совершаются с разных сайтов. Приложение должно генерировать отчет, отображая ежедневные или ежемесячные суммы транзакций и общую сумму дохода на веб-сайт. Я не хочу, чтобы сценарий отчета вычислял это каждый раз, поэтому мне нужно создать сводную таблицу, которая будет разбита на [сайт, дата].
Это просто один простой пример. Существует множество различных сводных таблиц, которые мне нужно создавать и поддерживать.
В прошлом я сделал это, написав несколько сценариев cron, чтобы обновлять каждую сводную таблицу. Но в этом новом проекте я надеюсь реализовать более элегантное и правильное решение.
Я предпочел бы решение на базе PHP, поскольку я не являюсь администратором сервера, и я чувствую себя наиболее комфортно, когда могу управлять всем через свой код приложения.
Решения, которые я рассмотрел:
Копирование вида по
Если результирующая таблица может быть представлена в виде одного запроса на выборку, я могу генерировать VIEW , Поскольку они медленные, может быть cronjob, который копирует этот VIEW в реальную таблицу.
Однако некоторые из этих запросов SELECT могут быть настолько медленными, что это неприемлемо даже для cronjobs. Не очень эффективно воссоздать все сводные данные, если старые строки даже не обновляются.
Пользовательские Cronjobs для каждой сводной таблицы
Это решение, которое я использовал раньше, но теперь я пытаюсь избежать, если это возможно. Если будет много сводных таблиц, это может быть беспорядочно поддерживать.
MySQL Триггеры
Можно добавить триггеры основных таблиц, так что каждый раз, когда есть INSERT, UPDATE или DELETE, сводные таблицы обновляется соответствующим образом.
Не было бы cronjobs, и резюме были бы в режиме реального времени. Однако, если когда-либо возникнет необходимость перестроить сводную таблицу с нуля, ее нужно будет сделать с помощью другого решения (вероятно, № 1 выше).
Использование ORM Крючки/Триггеры
Я использую Учение как мой ОРМ. Существует способ добавить прослушиватели событий, которые будут запускать материал в INSERT/UPDATE/DELETE, который, в свою очередь, может обновлять сводные таблицы. В некотором смысле это решение похоже на № 3 выше, но я буду лучше контролировать эти триггеры, поскольку они будут реализованы в PHP.
реализации соображения:
Полное перестроение
Я хочу, чтобы избежать необходимости восстановления сводных таблиц, для повышения эффективности, и только обновление для новые данные. Но в случае, если что-то пойдет не так, мне нужна возможность перестроить сводную таблицу с нуля, используя существующие данные в основных таблицах.
Игнорирование UPDATE/DELETE на Old Data
Некоторые итоги можно предположить, что старые записи не будут обновлены или удалены, но только новые записи будут вставлены. Сводный процесс может сэкономить много работы, сделав предположение, что ему не нужно проверять наличие обновлений для старых данных.
Но, конечно же, это не распространяется на все таблицы.
ведение журнала
Давайте предположим, что я не буду иметь доступ, или не хотите использовать двоичные протоколы MySQL.
Для обобщения новых данных сводный процесс просто должен запомнить последний идентификатор первичного ключа для последних суммируемых им записей. В следующий раз, когда он запустится, он может суммировать все после этого id. Однако, чтобы отслеживать старые записи, которые были обновлены/удалены, ему нужен еще один журнал, чтобы он мог вернуться и повторно суммировать эти данные.
Я был бы признателен за любые стратегии, предложения или ссылки, которые могут помочь. Спасибо!
Материализованные виды - это виды, которые можно индексировать (называемые «индексированные представления» в терминологии TSQL/SQL Server). Они, как известно, ограничены функциональностью, а MySQL их не поддерживает. MySQL едва поддерживает не материализованные представления, сравнивая функциональность с другими поставщиками. Oracle - это единственная другая БД, которую я знаю, которая поддерживает материализованные представления, помимо SQL Server. Я бы ожидал, что DB2 будет работать, но PostgreSQL этого не делает. –