Inteligencja Biznesowa – rozdział 2

https://xpil.eu/oyZeM

Dziś wracamy na poletko BI i kontynuujemy naszą wirtualną przygodę z biznesem marchwiowym.

Jak uważny czytelnik pamięta (używam liczby pojedynczej, ponieważ nie wierzę, że jest go więcej niż jeden), udało nam się już zapoznać z logiką biznesową, ustalić fakty, ujednolicić wymiary i właśnie zabieramy się za ładowanie danych. Zanim jednak zaczniemy, warto jeszcze zademonstrować użtytkownikom biznesowym (w naszym przypadku będą to: pan Stanisław, szef całego interesu, oraz być może jeszcze jego żona Krystyna) czego tak naprawdę mogą spodziewać się po wdrożeniu. Czyli spreparować, z użyciem niewielkiej ilości danych, próbkę raportów (wieńczących dzieło). Próbkę taką na ogół preparuje się w Excelu (lub innym karkuszu ("karkusz" to mój prywatny skrót na "arkusz kalkulacyjny")), do którego najpierw wkopiowuje się dane źródłowe, potem się je ręcznie koryguje i na koniec przedstawia wyniki w postaci tabeli przestawnej, która jest tworem dość dynamicznym i daje użytkownikowi możliwość "pobawienia się" raportem a nie tylko oglądania suchych cyferek.

Takie demo trzeba przygotować z głową, ponieważ na ogół dostęp do niego mają ludzie na najwyższych stanowiskach w firmie, i lepiej, żeby działało. Pan Stanisław może szybko zauważyć, że na raporcie demonstracyjnym średnia grubość marchwi w kłębie nie zgadza się z rzeczywistością, i może odwalić cały pomysł na wstępnym etapie (a zauważmy, że już zainwestowaliśmy w projekt sporo wysiłku) więc lepiej się do tego przyłożyć.

Jak już przejdziemy szczęśliwie przez fazę "demo", możemy zabrać się za ładowanie danych. W naszym przypadku jako "składzik na dane" zastosujemy bazę postgresql, ponieważ znamy tę technologię, a także ponieważ jeden z systemów (księgowość) już go używa, więc oszczędzimy sobie trochę pracy z kompatybilnością danych.

Uważny czytelnik zauważy, że pominąłem etap modelowania danych - mam cichy plan napisać kiedyś osobną serię artykułów na ten temat, więc tutaj nawet o tym nie wspomnę. Nie pisnę o modelowaniu danych ani słówkiem. A kursywą się nie liczy.

Ładowanie danych można zrealizować z wykorzystaniem kilku różnych metodologii. Najpopularniejsze są ETL oraz ELT (ETL: Extract -> Transform -> Load, ELT: Extract -> Load -> Transform). Zanim omówię różnice między ETL i ELT, wprowadzę jeszcze jeden termin: staging area. Nie mam bladego pojęcia jaki jest polski odpowiednik, w każdym razie jest to obszar naszej hurtowni danych gdzie trafiają dane z systemów źródłowych, oraz zgdzie następuje ich obróbka, normalizacja, usuwanie błędów zanim trafią do hurtowni właściwej jako fakty i wymiary.

W przypadku ETL w procesie ładowania danych do obszaru staging wybierane są tylko te dane źródłowe, które będą potrzebne do wygenerowania ostatecznych raportów; transformacja tych danych do postaci "jadalnej" dla docelowej hurtowni danych następuje tuż po (a często nawet w trakcie) ekstrahowania danych z systemów źródłowych. Zalety są takie, że nie trzymamy zbędnych danych w obszarze staging, a wady takie, że w razie rozbudowy hurtowni o nowe tabele / kolumny mamy więcej roboty. Jeszcze jedna zaleta (nietechnologiczna) jest taka, że większość rozwiązań DW opiera się na ETL, a więc jest to strategia bardziej popularna i łatwiej znaleźć na jej temat materiały w Sieci.

ELT natomiast polega na tym, że na początku wykonujemy kopię wszystkich danych źródłowych w staging, dopiero potem wybieramy i transformujemy to, co jest nam potrzebne w hurtowni - w ten sposób mamy zawsze "pod ręką" całość danych źródłowych (w postci kopii w staging) a nie tylko tą część, która jest niezbędna. W ten sposób rozbudowa hurtowni o nowe kolumny / tabele jest prostsza i szybsza - niestety, płacimy cenę w postaci większych wymagań sprzętowych (miejsce na dane). Ponadto, ponieważ ELT jest mniej popularne ni ETL, mamy mniejszy wybór jeśli chodzi o narzędzia programistzcyne.

Tak czy siak, musimy załadować komplet danych do hurtowni - najpierw kopiujemy wszystko "jak leci" do staging. Następnie musimy dane uporządkować i znormalizować - na przykład, zamiast dwóch tabel z nazwami gatunków marchwi ("M17" w jednej tabeli vs "Słodka Karotka" w drugiej), potrzebujemy dodatkowej "tabeli tłumaczącej" mapującej jedne nazwy na drugie. Tabela taka musi być "utrzymywana w świeżości" w taki sposób, żeby wszystkie odmiany, które mamy w firmie, były dodawane do tej tabeli na bieżąco. Dzięki temu system ładowania danych będzie "wiedział" która odmiana jest która, i wrzuci wszystkie do docelowej tabeli-wymiaru "marchew". Wymiar ma na ogół własny klucz unikalny, tzw "surrogate key" czyli klucz niemający znaczenia biznesowego, będący na ogół liczbą całkowitą najmniejszego możliwego typu - np. jeżeli wiemy, że na pewno nie będziemy mieć więcej niż 20-30 gatunków marchwi, wymiar "marchew" będzie miał klucz typu SMALLINT (używam typów z SQL Servera bo mi tak wygodnie) czyli liczba całkowita ośmibotowa (zakres wartości: 0 - 255). Jeżeli jednak będziemy ładować dod tabeli faktów identyfikatory pojedynczych marchewek (dane z systemu X na polu), przypuszczalnie marchewek tych będzie więcej niż 255 czy 65535, a po długim czasie być może nawet więcej niż 4294967295, a więc zastosujemy tam typ BIGINT (sprzedaż ponad 9 tryliardów marchewek wymagałaby najpierw zasiedlenia okolicznych systemów planetarnych, aż tak daleko nie musimy wybiegać w przyszłość).

Nie wiem nawet na jaką skalę trzeba rozkręcić biznes, żeby sprzedać ponad 4 miliardy marchewek - ale trzeba być optymistą. Steve Jobs składając "w garażu" swoje pierwsze NEXT-y też nie miał pojęcia, że wartość jego firmy przerośnie na pewnym etapie budżet Stanów Zjednoczonych.

Tak więc, marchew (jako wymiar w hurtowni danych) będzie miała swój "surrogate key" czyli lokalny identyfikator numeryczny, generowany z automatu przez system ładujący dane. Będzie też miała "alternate key" ("klucz alternatywny" zwany też "kluczem biznesowym"), czyli unikalny identyfikator pochodzący ze źródłowego systemu transakcyjnego (takim kluczem może być na przykład oznaczenie gatunku marchwi: M17, M17Z, M18 itd). Ważne jest, aby zapewnić unikalność tego klucza - a przede wszystkim nie ufać źródłu i sprawdzać tę unikalność przy każdym ładowaniu nowych gatunków marchwi. Klucz biznesowy jest też używany do aktualizacji danych - na przykład, jeżeli ktoś omyłkowo wpisał "Słodka Kaortka" i dwa dni później poprawi literówkę, poprawka musi trafić do hurtowni - i musi zmienić istniejący wpis a nie utworzyć nowy.

Tak więc nasz wymiar "marchew" będzie miał: klucz lokalny (surrogate key), klucz biznesowy, oznaczenie kodowe "z pola", nazwę marketingową, być może do tego jeszcze dojdzie data rozpoczęcia hodowli, data rozpoczęcia sprzedaży, i na pewno kilka kolumn do późniejszego audytu danych, a więc: czas utworzenia rekordu, czas ostatniej modyfikacji, nazwa użytkownika, który ostatnią modyfikację przeprowadził, być może jeszcze numer procesu, który utworzył / zmodyfikował rekord. Dzięki temu łatwiej potem wyszukać kto-co-gdzie-kiedy w razie potrzeby.

A co zrobić z wpisami, które mają błędy? Dajmy na to, nowa odmiana jest już "na polu", ale ktoś nie wprowadził jej do "tabeli tłumaczącej" w związku z czym nie da się danych załadować. Takie dane są na ogół przekierowywane w osobne miejsce, gdzie mogą być przejrzane przez uprawnioną osobę, a następnie mogą być podjęte decyzje czy dane można zignorować, czy też trzeba wprowadzić korektę w systemie źródłowym bądź w systemie ładowania danych. Na ogół jest to zrealizowane w postaci osobnej tabeli (lub tabel) przechowującej szczegółowy log błędów ładowania.

OK, załóżmy, że mamy już opracowane ładowanie wymiarów, a co z faktami? Podstawowa sprawa dotycząca tabel faktów jest taka, żeby trzymać te tabele w miarę "wąskie". A więc, żadnych danych tekstowych (może z wyjątkiem wymiarów zdegenerowanych - o tym za chwilę), wszystkie dane numeryczne zdefiniowane przy użyciu najmniejszych typów danych, wszystkie połączenia do tabel wymiarów wyłącznie przy użyciu "surrogate keys". Pamiętajmy, że tabela faktów będzie zawsze rosła, i to w szybkim tempie - tak więc przeszacowanie typu danych z INT na BIGINT może skutkować zwiększeniem zużycia miejsca o 4 bajty na rekord (w przypadku stu rekordów to jest do pominięcia, ale jak już mamy miliardy rekordów, możemy zaoszczędzić - lub zmarnować - gigabajty).

Wróćmy do naszej marchwi - ładujemy dane z pola (raz dziennie), ładujemy dane sprzedażowe (prawdopodobnie też raz dziennie), generujemy świeże dane dla hurtowni - i tak w kółko Macieju. Załatwiliśmy kwestię danych i mamy teraz te dane w postaci "jadalnej" do raportowania.

Ach, prawda, wymiar zdegenerowany - cóż to za stwór? Wymiar "zwykły" zazwyczaj jest reprezentowany w postaci osobnej tabeli z kluczem lokalnym (surrogate key), kluczem biznesowym oraz kilkoma atrybutami (nazwa, druga nazwa, jakieś daty, informacja czy marchew jest eksperymentalna czy do sprzedaży etc etc). Jednak niektóre wymiary nie wymagają osobnej tabeli, ponieważ składają się wyłącznie z jednej, niedużej części tekstowej Są to na ogół wszelakie identyfikatory nadawane przez systemy źródłowe obiektom typu faktura, zamówienie itd. Na przykład numer faktury "FV123456789PL" może być potrzebny w tabeli faktów (żeby wyszukać daną fakturę), ale nie ma sensu budować tutaj osobnego wymiaru (jako tabeli), ponieważ nie byłoby tam żadnych innych pożytecznych atrybutów. To jest właśnie wymiar zdegenerowany.

Co dalej?

A nie wiem, poczekajmy parę dni, niech się hurtownia naje porządnie marchwią, zobaczymy czy uda nam się z tego wysrać jakieś raporty...

https://xpil.eu/oyZeM

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.