MySql: Разумно ли использовать 'view', или мне лучше денормализовать мою БД? - PullRequest
3 голосов
/ 02 января 2011

Существует таблица 'team_sector' со следующими полями: Id, team_id, sect_id, size, level

Он содержит несколько записей для каждой сущности 'team' (на которую ссылается поле 'team_id'). Каждая запись представляет сектор стадиона команды (всего 8 секторов).

Теперь необходимо реализовать несколько поисков:

  • от общего размера стадиона (SUM (размер));
  • лучшее качество (СУММА (уровень) / СЧЕТ (*)).

Я мог бы создать запрос примерно так:

SELECT TS.team_id, SUM(TS.size) as OverallSize, SUM(TS.Level)/COUNT(TS.Id) AS QualityLevel
FROM team_sector
GROUP BY team_id
ORDER BY OverallSize DESC / ORDER BY QualityLevel DESC

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

Здесь я вижу 2 варианта.

Первое - создать 2 дополнительных поля в таблице «команда» (например) и сохранить там поля «Общий размер» и «Уровень качества». Если информация об изменении таблицы 'секторов' изменилась, обновите и эти таблицы (вероятно, было бы хорошо сделать это с помощью триггеров, поскольку таблица секторов меняется не слишком часто).

Второй вариант - создать представление, которое предоставит необходимые данные.

Второй вариант мне кажется намного проще, но у меня нет большого опыта / знаний по работе с представлениями.

Q1: Каков наилучший вариант с вашей точки зрения и почему? Возможно, вы могли бы предложить другие варианты?

Q2: Могу ли я создать представление таким образом, чтобы оно выполняло вычисления редко (хотя бы раз в день)? Если да - как?

Q3: Разумно ли использовать триггеры для этой цели (1-й вариант).

P.S. Используется MySql 5.1, общее количество команд составляет около 1-2 тысяч, общее количество записей в таблице секторов - всего 6-8 тысяч. Я понимаю, что эти цифры довольно малы, но я хотел бы применить здесь лучшие практики.

Ответы [ 2 ]

2 голосов
/ 02 января 2011

Я бы не добавил вычисляемые поля в ваши исходные таблицы.Держите ваши исходные данные отдельно от расчетных данных, используя вместо этого временные таблицы.Вы можете использовать взаимно-однозначное сопоставление, определяемое совместно используемым PK, чтобы повысить производительность за счет снижения индексов и т. Д. (Таким образом, PK исходных строк равен PK строк в вычисляемой таблице).когда вы перестраиваете БД, ясно, что расчетные данные устарели из-за отсутствия таблиц.Это также позволяет использовать такие ярлыки, как очистка всех вычисленных данных путем простого удаления временных таблиц, например, с помощью задания cron.Таким образом, вычисленные строки данных могут также сохранять временную метку, когда были рассчитаны данные.Таким образом, если максимальный период кэширования истек, вычисленные данные могут быть пересчитаны на лету, когда они загружаются, или в виде пакета ночью, когда серверы работают тихо.

1 голос
/ 02 января 2011

Несколько (десять) тысяч записей - это не то, о чем вам следует беспокоиться.

Лучшие практики

  • хранит данные в нормализованном порядке и позволяет ядру базы данных обрабатывать вычисления
  • правильно проиндексируйте ваши данные, время от времени проводите обслуживание индекса
  • избегать хранения агрегированных значений с «родительскими» записями
  • выполнить некоторое кэширование результатов на уровне приложений, чтобы избежать попадания на сервер БД чаще, чем это необходимо
  • справляется с проблемами производительности, когда вы их получаете

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

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

ИМХО, предвидеть возможные узкие места в производительности и "закрывать" их до того, как они действительно появятся, тратить ваше время.

...