EDW #10: Data Marts

https://xpil.eu/rso

Dotychczas omówiliśmy sobie pięć z siedmiu warstw logicznych hurtowni danych. Dziś czas na warstwę szóstą: Data Marts (w skrócie: DMARTS albo DM).

Jest to ostatnia warstwa hurtowni, nad którą mamy pełną kontrolę. Dane w warstwie DMARTS pochodzą bezpośrednio z EDW, a więc z punktu widzenia jakości danych jest to warstwa równie solidna, jak bezpośrednio ją poprzedzająca EDW.

DMARTS to warstwa "dla leniwych" (cudzysłów zamierzony). Dane tutaj są poukładane w sposób łatwy do konsumpcji przez warstwę siódmą (i ostatnią), czyli konsumentów danych - końcowych użytkowników hurtowni.

Dane w DMARTS są zdenormalizowane (o denormalizacji wspominałem w drugim odcinku serii), co znacznie upraszcza przeprowadzanie analiz ad-hoc i zwalnia końcowego użytkownika od konieczności "rozgryzania" zależności między poszczególnymi encjami w hurtowni.

Nie ma jednoznacznego przepisu na to, co powinno a czego nie powinno być w DMARTS. Potrzeby tworzenia obiektów w tej warstwie są dyktowane potrzebami użytkowników końcowych.

W "czystej" formie w DMARTS powinny znajdować się tylko dwa rodzaje tabel: fakty i wymiary, przy czym "fakty" będą tu już na ogół "wzbogacone" atrybutami ze skojarzonych z nimi wymiarów. Zwyczajowo nazwy tabel w dmarts poprzedza się przedrostkami D_ i F_ aczkolwiek oczywiście standardy nazewnictwa każdy może sobie narzucić we własnym zakresie. Ważne, żeby konsument wiedział, czy ma do czynienia z danymi transakcyjnymi (fakty, F_) czy opisowymi (wymiary, D_).

Oczywiście "czysta" forma istnieje wyłącznie w wyobraźni teoretyków i purystów. W rzeczywistości oprócz faktów i wymiarów zazwyczaj dochodzą jeszcze tabele pomocnicze. Na przykład zagregowane pomosty między dwoma wymiarami (to ostatnie brzmi trochę jak fragment z powieści SF, ale to może innym razem). Załóżmy, że mamy wymiar D_KLIENT oraz inny wymiar, D_TYP_TRANSAKCJI. I że chcemy dać konsumentowi możliwość szybkiego sprawdzenia, ile razy każdy z klientów wygenerował transakcje różnych typów. Oczywiście można w tym celu po prostu dać użytkownikowi do dyspozycji fakt F_TRANSAKCJE z danymi wyciągniętymi z tabeli EDW.TRANSAKCJA plus podpięte do niej tabele EDW.KLIENT i EDW.TYP_TRANSAKCJI - ale w takim przypadku konsument musi sobie policzyć ilości transakcji poszczególnych typów per klient samodzielnie. Niektórzy użytkownicy sobie z tym poradzą. Inni - niekoniecznie. Dlatego dla ułatwienia tworzymy tabelę DMARTS.AGG_KLIENT_TYP_TRANSAKCJI, w której udostępniamy wyłącznie dane zagregowane na poziomie szczegółowości pojedynczego klienta. Możemy to tego dołożyć drugą tabelę: DMARTS.AGG_TYP_TRANSAKCJI_KLIENT, która będzie robiła coś odwrotnego: pokazywała ilu klientów wygenerowało poszczególne typy transakcji. A więc: bardzo niewiele rekordów (ile możemy mieć typów transakcji? trzy? pięć? dziesięć?) z dużymi licznikami.

Innym "dodatkowym" typem tabeli w DMARTS może być tabela łącząca dwa różne fakty. Coś, co zazwyczaj wymaga JOIN-a między dwiema stosunkowo dużymi tabelami z EDW, może być zmaterializowane w postaci gotowej do konsumpcji tabeli w DMARTS. Przykładowo możemy sobie wyobrazić tabelę faktów ZAMÓWIENIA oraz drugą, FAKTURY - obydwie dotyczą w zasadzie tego samego procesu, ale innych jego etapów. Nie do każdego zamówienia będzie faktura, nie do każdej faktury będzie zamówienie, ale w większości przypadków będzie istnieć między nimi połączenie. I tu możemy stworzyć "pomost" między faktami, kojarzący rekordy z jednej tabeli z rekordami z drugiej. W warstwie EDW będzie to tabela "faktopodobna", w takim sensie, że będzie miała bardzo dużo rekordów, za to tylko dwie wąskie kolumny: ID faktury i ID zamówienia. Natomiast w warstwie DMARTS wywleczemy wszystkie "strawne" kolumny z obydwu tabel spiętych ww. pomostem, plus ewentualne wymiary i wszystko zapiszemy jako DMARTS.B_ZAMOWIENIA_FAKTURY (przedrostek B_ oznacza tu "bridge" czyli "pomost" między dwoma faktami).

Powyższy scenariusz jest tylko jednym z wielu możliwych - w rzeczywistości możemy mieć 1:1 między pojedynczą pozycją w zamówieniu, a pojedynczą pozycją na fakturze, albo nawet n:m między nimi - i tak dalej

Oczywiście wszystko zależy tutaj od tego, w jaki sposób wymodelujemy dane w hurtowni. Zamówienie => Faktura => Płatność => Dostawa to tak naprawdę etapy tego samego procesu i można je wymodelować w jednej tabeli / grupie tabel, zamiast kombinować z ich rozbijaniem na części, a następnie budowaniem między tymi częściami pomostów. Ale tu tuż schodzimy na tematy niezwiązane z DMARTS. Może więc innym razem.

Wracając do Data Marts: najczęściej będzie tak, że dane w tej warstwie będą zmaterializowane (a więc: tabela lub przynajmniej materialized view), ale czasami dla niewielkich encji można sobie pozwolić na utworzenie zwykłych widoków (view) ciągnących dane bezpośrednio z EDW, dla uproszczenia ETL.

Dość powszechną praktyką jest też "pivotowanie" danych z EDW do DMARTS. Jeżeli mamy w EDW dane z kilku lat, możemy w DMARTS stworzyć tabelę, której poszczególne kolumny będą reprezentowały kolejne lata. Rozwiązanie jest o tyle nieelastyczne, że raz do roku trzeba zmieniać tę tabelę (dokładać oklejny rok), ale można ten problem "obejść" używając kolumn typu "ROK_BIEZACY", "ROK_MINUS_1", "ROK_MINUS_2" i tak dalej. Wszystko zależy od tego, czego oczekują do DMARTS użytkownicy końcowi.

Kolejna sprawa, dotycząca zarówno EDW jak i DMARTS, to utrzymywanie "porządku" w referencjach między tabelami. A więc jeżeli mamy fakt F_FAKTURA i podpięty do niego wymiar D_KLIENT, to stwórzmy między nimi referential integrity constraint, dzięki czemu nie tylko unikniemy duplikacji danych, ale dodatkowo poprawimy wydajność wykonywania zapytań, jak również uprościmy pracę warstwie siódmej (czyli konsumentom danych z naszej hurtowni). Niektóre platformy raportujące potrafią rozpoznać "połączenia" między tabelami, jeżeli takie połączenia - właśnie w formie referential integrity constraints - stworzymy na poziomie bazy danych.

Ostatnia, dość istotna sprawa, o której warto pamiętać: DMARTS jest dla użytkowników końcowych, a więc postarajmy się tu zminimalizować ilość atrybutów technicznych, eksponując głównie atrybuty biznesowe. Klienta nie interesuje, jakie ID nadaliśmy z lokalnej sekwencji jego fakturze. Użytkownika interesuje numer faktury.

Za tydzień postaram się - o ile czas i chęci pozwolą - na zbudowanie prościutkiego przykładu obrazującego "przejście" między warstwami EDW i DMARTS.

https://xpil.eu/rso

Leave a Comment

Komentarze mile widziane.

Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]

Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.