2

Я создаю приложение Analytics, где мы отслеживаем конверсии для кампаний маркетинга компаний. Конвертация - если они идут в супермаркет и покупают продукт. Если компания Heinz, они могут работать кампании для различных продуктов, поэтому кампании могут быть:Подходящий дизайн модели данных (RDBMS) для множественных перестановок данных

  • Запеченная фасоль
  • Томатный суп
  • Кетчуп

Это онлайн кампании, чтобы они могли различные медиумы, такие как:

  • Сайт
  • Facebook страницу
  • Flash Banner Ad
  • Mobile App Ad

И если кто-то покупает продукт, он купил через супермаркет, такие как:

  • Walmart
  • Asda
  • Safeway
  • Kroger

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

  • для запеченных боб.
  • для запеченных бобы со страницы Facebook.
  • для супермаркета Walmart, но для всех Кампании & Средние.
  • для Walmart со страницы Facebook, но для всех кампаний.
  • для кетчупа, сделанного с помощью рекламного баннера Flash и для Safeway.

Чтобы быстро сделать аналитику, мы избегаем обработки необработанных данных (миллионы записей), но сохраняем агрегированную версию данных, хранящихся в день. Итак, в течение 12 сентября я могу записать, что у нас было 12 конверсий для Baked Beans, 6 конверсий (для всех продуктов) были сделаны через веб-сайт, а Walmart - 8 конверсий, и они могут быть в 3 отдельных таблицах (так называемые Кампании, Средних и супермаркетов). Но если мне нужно знать конверсии для кетчупа, сделанные через страницу Facebook, а для Walmart, то хранение в отдельных таблицах очевидно не будет работать.

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

ответ

3

Да, есть лучшая стратегия. Это называется Dimensional Modeling или Star Schema.

Вы храните один стол под названием Таблица фактов, в которой есть столбцы для кампании, среднего и супермаркета.

Для каждого из этих атрибутов столбец в таблице фактов является внешним ключом для таблицы Таблица размеров. Одна таблица измерений для каждого, Кампании, Средние и Супермаркеты.

В вашем случае, чтобы избежать миллионов строк, вы можете добавить четвертую колонку в таблицу фактов, conversions. Увеличивайте счетчик, когда вы получаете конверсию (в отличие от добавления другой строки).

Вот пример таблицы:

CREATE TABLE FactTable (
    campaign_id INT, 
    medium_id INT, 
    supermarket_id INT, 
    conversions INT, 
    PRIMARY KEY (campaign_id, medium_id, supermarket_id), 
    FOREIGN KEY (campaign_id) REFERENCES Campaigns(campaign_id), 
    FOREIGN KEY (medium_id) REFERENCES Mediums(medium_id), 
    FOREIGN KEY (supermarket_id) REFERENCES Supermarkets(supermarket_id) 
); 

Тогда вы можете запросить для всех преобразований:

  • для печеных бобов.

    SELECT SUM(conversions) FROM FactTable 
    JOIN Campaigns USING (campaign_id) 
    WHERE campaign = 'Baked Beans'; 
    
  • для хлебобулочных изделий со страницы Facebook.

    SELECT SUM(conversions) FROM FactTable 
    JOIN Campaigns USING (campaign_id) 
    JOIN Mediums USING (medium_id) 
    WHERE campaign = 'Baked Beans' AND medium = 'Facebook'; 
    
  • для супермаркета Walmart, но и для всех кампаний & медиумов.

    SELECT SUM(conversions) FROM FactTable 
    JOIN Supermarkets USING (supermarket_id) 
    WHERE supermarket = 'Walmart'; 
    
  • для Walmart сделан со страницы Facebook, но для всех кампаний.

    SELECT SUM(conversions) FROM FactTable 
    JOIN Mediums USING (medium_id) 
    JOIN Supermarkets USING (supermarket_id) 
    WHERE medium = 'Facebook' AND supermarket = 'Walmart'; 
    
  • для кетчупа, сделанного с помощью рекламного баннера Flash и для Safeway.

    SELECT SUM(conversions) FROM FactTable 
    JOIN Campaigns USING (campaign_id) 
    JOIN Mediums USING (medium_id) 
    JOIN Supermarkets USING (supermarket_id) 
    WHERE campaign = 'Ketchup' AND medium = 'Flash Banner Ad' AND supermarket = 'Safeway'; 
    

books by Ralph Kimball Заканчивать для получения дополнительной информации трехмерного моделирования.

+1

Легко в Top 5 лучших ответов Stackoverflow, которые у меня когда-либо были! Большое спасибо :-) –

+0

Не только хороший ответ, но и очень хорошо сформулированный. Я бы добавил, что во многих случаях клиентское приложение имеет целочисленный id (или какой-то uuid для публичного api), встроенный в элемент управления, который отображает имена. Таким образом, нет необходимости в соединениях ... только условие WHERE, определяющее идентификаторы (id). Даже быстрее. – NaturalData

+0

@NaturalData, да, это хорошая оптимизация, я показывал объединения, потому что это очень хорошо иллюстрирует роль таблиц измерения. –

2

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

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

Смежные вопросы