SQL: соединения против денормализации (много данных) - PullRequest
3 голосов
/ 11 октября 2011

Я знаю, варианты этого вопроса задавались ранее. Но мой случай может быть немного другим: -)

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

Мне нужно быстро получить ответы на два вопроса:

  • получить количество событий от пользователей с определенным профилем (например, мужчины в возрасте 18-25 лет из Москвы, Россия)
  • получить сумму (возможно, также и среднюю) значений событий от пользователей с определенным профилем -

Кроме того, данные генерируются несколькими клиентами, которые, в свою очередь, могут иметь несколько source_ids.

Схема доступа: данные будут в основном записываться процессами сборщика, но при запросе (нечасто, через веб-интерфейс) он должен отвечать быстро.

Я ожидаю, что МНОГО данных, безусловно, могут обрабатываться более чем одной таблицей или одним сервером.

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

Итак, вопрос: что делать с атрибутами пользователя?

Нормализованный вариант 1: сохранить их в отдельной таблице и ссылках из таблиц событий.

  • (pro) Нет повторения данных.
  • (con) соединения, которые стоят дорого (или около того) Я слышал).
  • (con) это требует включения таблицы пользователя и таблицы событий тот же сервер

Вариант 2, избыточный: хранить пользовательские атрибуты в таблицах событий и индексировать их.

  • (pro) упрощенная балансировка нагрузки (можно перемещать автономные таблицы)
  • (pro) простых (быстрее?) Запросов
  • (con) много дискового пространства и памяти, используемой для повторения пользовательских атрибутов и соответствующих индексов

Ответы [ 3 ]

6 голосов
/ 11 октября 2011

Ваш дизайн должен быть нормализован, физическая схема может оказаться денормализованной по соображениям производительности.

Возможно ли сделать оба? Существует причина, по которой SQL Server поставляется с Analysis Server. Даже если вы не в сфере Microsoft, обычно существует транзакционная система для ввода данных и повседневной обработки, в то время как система отчетов доступна для видов запросов, которые могут вызвать большие нагрузки на транзакционную систему.

Это означает, что вы получаете лучшее из обоих миров: нормализованную систему для ежедневных операций и денормализованную систему для сводных запросов.

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

3 голосов
/ 11 октября 2011

Используйте подход OLAP / Хранилище данных.То есть храните ваши данные стандартным нормализованным способом, а также храните агрегированные версии данных, которые будут часто запрашиваться в отдельных таблицах фактов.Пользовательские запросы не будут относиться к данным в реальном времени, но это обычно стоит компромисса с производительностью.

Кроме того, если вы используете SQL Server Enterprise, я бы не стал использовать собственную схему горизонтального разбиения(разбивая данные на дни).В сервер SQL встроены инструменты, которые автоматически сделают это за вас.

1 голос
/ 11 октября 2011

Пожалуйста, нормализуйте

использовать разделы и индексирование для балансировки нагрузки

...