Дизайн сховища даних: комбінований розмір дати та порівняно з окремими розмірами дня та часу та часові пояси


10

Ми тільки починаємо розробку нового сховища даних і намагаємось розробити, як працюватимуть наші параметри дати та часу. Нам потрібно мати можливість підтримувати декілька часових поясів (можливо, принаймні GMT, IST, PST та EST). Ми спочатку думали, що у нас буде один широкий комбінований часовий вимір до, можливо, 15-ти хвилинної деталізації, таким чином, у нас є один ключ у наших таблицях фактів, а всі різні часові дані дати для всіх підтримуваних часових поясів знаходяться в одній таблиці вимірів. (тобто ключ дати, дата GMT, час GMT, дата IST, час IST тощо)

Kimball пропонує мати окремий розмір дня від розміру часу, щоб запобігти зростанню таблиці занадто великим (набір інструментів сховища даних стор. 240), але це чудово звучить, але це означає, що у наших таблицях фактів для кожного часового поясу є дві клавіші нам потрібно підтримати (один на дату і один на час доби).

Оскільки я дуже недосвідчений в цій галузі, я сподіваюся, що хтось там знає компроміси між двома підходами, тобто ефективність та управління всіма ключами часового поясу. Можливо, є й інші підходи. Я бачив, як деякі люди говорять про наявність окремого рядка в таблиці фактів за часовим поясом, але це здається проблемою, якщо фактичні таблиці - це мільйони рядків, то вам потрібно в чотири рази їх додати часові пояси. .

Якщо ми зробимо 15-хвилинне зерно, у нашій таблиці виміру часу на дату буде 131,400 (24 * 15 * 365) рядків на рік, що не звучить занадто жахливо для продуктивності, але ми не будемо точно знати, поки не перевіримо деякі запити прототипу. Інша проблема, пов'язана з наявністю окремих таблиць часового поясу в таблиці фактів, полягає в тому, що запит повинен приєднати таблицю вимірів до іншого стовпця на основі потрібного часового поясу. Можливо, це те, про що піклується SSAS, я не впевнений .

дякую за будь-які думки, -Мат


1
Це питання також існує в переповнення стека: stackoverflow.com/questions/2507289/… .
Йон усіх торгів

Відповіді:


5

Якщо розділити дату та час, ви зможете робити агрегати за часом набагато легше. наприклад: якщо ви хочете запустити запит, щоб визначити, який часовий період дня найбільш зайнятий. Це набагато легко виконати, використовуючи окремий часовий вимір.

Крім того, ви повинні мати лише один тайм-ключ. Вирішіть чи GMT / EST час - тоді використовуйте це у таблиці фактів. Якщо вам потрібно запускати звіти за іншим часовим поясом, просто перетворіть їх у свою програму чи запит.


Гаразд, це має сенс, користувачі не можуть згрупувати дані потім на основі свого часового поясу, але це, мабуть, те, що ми могли б жити без того, щоб спростити дизайн.
Метт Палмерлі

@MattPalmerlee: Користувачі можуть групувати за часовим поясом, якщо ви їм надаєте їх. Я зазвичай включаю його в Geographyтаблицю, але якщо нічого не застосовується, ви можете додати його як атрибут вашої таблиці фактів.
Йон усіх торгів

5

Лише далі про те, як ми вирішили впровадити наш DataWarehouse для підтримки декількох часових зон та бути максимально ефективними: ми вирішили створити таблицю часових поясів (ідентифікатор, ім’я тощо), а також "часову зону. таблиця міст ", яка виглядає приблизно так:

time_zone_bridge
---------------
date_key_utc
time_key_utc
timezone_id
date_key_local
time_key_local

Таким чином ми можемо зберегти наші нормальні таблиці розмірів дати та часу невеликими, всі наші факти посилаються на клавіші дати / часу UTC, тоді, якщо нам потрібно повідомити / групувати за іншим часовим поясом, нам просто потрібно приєднатися через таблицю мосту часового поясу і зв’язати локальні клавіші дати / часу назад до таблиць виміру дати та часу. Ми заповнюємо таблицю мосту часового поясу за допомогою коду C #, викликаного від SSIS, оскільки це було набагато складніше, ніж робити TZ речі безпосередньо з SqlServer.


Я також думаю, що ваше рішення, мабуть, має найбільш сенс, не вникаючи в щось занадто складне. Я тестую свій DW за допомогою таблиці timeZone та TimeZoneBridge, аналогічної вашій. Він також має таблиці TimeDimension та DateDimension. Я створив кластерний індекс на date_key_local, time_key_local та timezone_id, так що переклад місцевого часу на час UTC за допомогою TimeZoneBridge був би швидким.
dsum

1
Наш основний кластерний ключ для таблиці містків знаходиться у стовпцях дата / час + ідентифікатор часового поясу (якщо я правильно пам’ятаю), оскільки всі часові клавіші таблиць фактів будуть в utc, ви приєднаєтесь до мосту через utc клавіші + tz id, може бути краще, щоб кластерний індекс був на них. Робіть те, що має сенс для ваших потреб. Я радий, що моя відповідь комусь допомогла, я вважаю, що це хороший підхід, і, зважаючи на тестування, це все ще досить швидко, просто будьте обережні, якщо мова йде про пункт WHERE: відфільтруйте потрібні діапазони дат можливо у ваших запитах.
Метт Палмерлі

Чи містить це лише цілі дати? Або якщо у таблиці фактів ви маєте 86000 значень "ключ / дата", таблиця моста матиме 86000 рядків * n підтримуваних часових поясів, і це лише за цей день?
Аарон Бертран

1
можливо, ви можете додати точне визначення таблиці, яке у вас є, щоб читачі могли бачити основні, унікальні обмеження.
ypercubeᵀᴹ

@AaronBertrand це залежить від зерна (або деталізації, який ви обираєте) для відстеження ваших даних, у нашому випадку нам потрібно було лише 15-хвилинну деталізацію в наших фактичних таблицях, тому це лише 4 * 24 = 96 записів на день за часовий пояс, який ми хотіли підтримувати, що цілком розумно.
Метт Палмерлі

2

Я бачив, що ідея складу з комбінованим DateTimeрозміром відхилена, але я не бачив дійсно зрозумілої причини. Трохи спрощуючи, ось таблиця фактів, яку я зараз будую:

Transactions
(
...
CreatedDateTimeSK         INT NOT NULL,  -- Four bytes per date...
AuthorizedDateTimeSK      INT NOT NULL,
BatchSubmittedDateTimeSK  INT NOT NULL,
BatchApprovedDateTimeSK   INT NOT NULL,
SettlementDateTimeSK      INT NOT NULL,
LocalTimeZoneSK           TINYINT NOT NULL  -- ...plus one byte for the time zone
)

В DateTimeполе приєднатися до таблиці DateTime:

DateTimes
(
DateTimeSK   INT NOT NULL PRIMARY KEY,
SQLDate      DATE NOT NULL,
SQLDateTime  DATETIME2(0) NOT NULL,
Year         SMALLINT NOT NULL,
Month        TINYINT NOT NULL,
Day          TINYINT NOT NULL,
Hour         TINYINT NOT NULL,
Minute       TINYINT NOT NULL CHECK (Minute IN (0, 30)),
...
)

Це з роздільною здатністю півгодини, тому в день є 48 записів, 350 400 за 20 років - цілком керовані.

Дата / час події перекладається на UTC, коли вони зберігаються, але за допомогою LocalTimeZoneSKполя та таблиці містків ми можемо легко приєднатися до місцевого часу:

TimeZoneBridge
(
DateTimeSK       INT NOT NULL,
TimeZoneSK       TINYINT NOT NULL,
PRIMARY KEY (DateTimeSK, TimeZoneSK),
LocalDateTimeSK  INT NOT NULL
)

Щоб отримати транзакції, створені сьогодні, час UTC:

SELECT COUNT(*)
FROM Transactions AS T
  INNER JOIN DateTimes AS CD ON T.CreatedDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'

Щоб отримати транзакції, створені сьогодні, у місцевий час для проведення транзакції:

SELECT COUNT(*)
FROM Transactions AS T
  INNER JOIN TimeZoneBridge AS TZB ON T.CreatedDateTimeSK = TZB.DateTimeSK AND T.TimeZoneSK = TZB.TimeZoneSK
  INNER JOIN DateTimes AS CD ON TZB.LocalDateTimeSK = CD.DateTimeSK
WHERE CD.SQLDate = '2014-08-22'

Ви можете захотіти , щоб спростити речі, замінивши TimeZoneSKз REALзміщенням (наприклад, -5,0 для США Центральної поясним часом), але це буде руйнуватися , якщо деякі дати / часу для запису фактів в літню пору , а деякі ні.

Якщо події для запису фактів можуть відбуватися в різних часових поясах, наприклад, відправлення або рейс, тоді вам потрібно поле часового поясу для кожної дати, і ви маєте до п'яти байтів на дату.


Це творчий підхід. Однак, як ви кажете, у вашій комбінованій тьмяній таблиці за датою буде лише 350 400 рядків, якщо ви почнете змінювати зерно на більш чітку роздільну здатність, ви швидко потрапите в мільйони записів. Якщо ви вирішите мати окремий розмір дати, ніж часовий, у вашій таблиці таблиці часу лише 48 рядків і лише 365 рядків на рік у таблиці розмірів дати (або 7300 рядків за 20 років). Тоді у вашій таблиці фактів просто є стовпець для дати_кейку та тайм-ключа. Це також робить його більш гнучким, якщо у вас є декілька таблиць фактів, для яких потрібна лише деталізація дати.
Метт Палмерлі

1
Міліон рядків у вимірі мене не стосується - дані змінюються лише раз на десятиліття, а індекс покриття ПК та два-три найпоширеніші поля займатиме тривіальний об'єм оперативної пам'яті сервера. Однак додавання півдесятка SMALLINTs до таблиці з фактами в мільярд рядків становить 12 ГБ плюс накладні витрати, і тепер ви говорите про реальні гроші. Для дат, для яких потрібно зберігати дату, можна, звичайно, вказати їх на запис "00:00 ранку" на відповідну дату.
Джон з усіх торгів
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.