Ten wpis nale偶y do serii wpis贸w po艣wi臋conych architekturze hurtowni danych.
Tytu艂 dzisiejszego wpisu nieco pachnie rekurencj膮, ale to tylko poz贸r. Tak wysz艂o. Albowiem omawia膰 dzi艣 b臋dziemy najwa偶niejsz膮 z warstw logicznych hurtowni danych, czyli warstw臋 EDW.
EDW przechowuje dane w postaci znormalizowanej (na og贸艂 3NF lub prawie-3NF - po szczeg贸艂y odsy艂am do Wikipedii). G艂贸wny model danych (o modelowaniu by膰 mo偶e napisz臋聽kilka odcink贸w w tej serii, a mo偶e nawet po艣wi臋c臋 mu osobn膮 seri臋, bo temat jest niew膮ski) zawiera w艂a艣nie tabele z warstwy EDW. To tutaj mieszkaj膮 wszystkie encje naszej hurtowni, w postaci w zasadzie gotowej do konsumpcji przez ko艅cowych odbiorc贸w. Warstwa EDW jest zaufana, poniewa偶 - o ile tylko mamy w naszej hurtowni danych jakiekolwiek rozwi膮zanie typu DQ czy MDH - w艂a艣nie do niej trafiaj膮 dane przefiltrowane przez systemy kontroli jako艣ci danych (w jaki spos贸b? by膰 mo偶e uda mi si臋 po艣wi臋ci膰 temu osobny wpis).
Przy okazji wyja艣ni艂o si臋, dlaczego przez ca艂膮 t臋 seri臋 u偶ywam skr贸tu DW a nie EDW - w艂a艣nie po to, 偶eby si臋 te dwa skr贸ty nie pokitwasi艂y.聽
Nazwy tabel
Tabele w warstwie EDW nazywamy tak, jak nazwane s膮 encje w modelu fizycznym. Czyli: KLIENT, FAKTURA, WPIS, RODZAJ_OPERACJI i tak dalej. Nie ma 偶adnych prefiks贸w, 偶adnych ozdobnik贸w itp. Jest samo g臋ste.
Identyfikatory
Ka偶da tabela w EDW ma unikalny identyfikator numeryczny, wygenerowany w trakcie wype艂niania warstwy XREF (o ile encja pochodzi z wi臋cej ni偶 jednego systemu 藕r贸d艂owego) b膮d藕 te偶 bezpo艣rednio na poziomie EDW, je偶eli encja ma tylko jedno 藕r贸d艂o (w kt贸rym to przypadku warstwy Landing / XREF s膮 pomijane i EDW 艂adujemy bezpo艣rednio ze Stage).
Na og贸艂 identyfikatory te generowane s膮 z globalnej (dla ca艂ej hurtowni) sekwencji typu BIGINT, dzi臋ki czemu po pierwsze gwarantujemy globaln膮 unikalno艣膰 ka偶dego identyfikatora w ca艂ej hurtowni, a po drugie - co czasem si臋 przydaje, a czasem nie - mo偶emy 艂atwo stwierdzi膰, kt贸ry rekord by艂 wygenerowany wcze艣niej, a kt贸ry p贸藕niej. Tak czy siak, unikalny identyfikator rekordu w ka偶dej tabeli w EDW jest zawsze pojedyncz膮 kolumn膮 ca艂kowitoliczbow膮.
Opr贸cz tego ka偶da tabela w EDW powinna mie膰 za艂o偶ony indeks unikalny na kolumnach odpowiadaj膮cych kluczowi biznesowemu.
Raz jeszcze powt贸rz臋 kluczow膮 cech臋 warstwy EDW: ka偶da tabela w tej warstwie odpowiada dok艂adnie jednej encji w hurtowni. Je偶eli mamy pi臋tna艣cie r贸偶nych system贸w 藕r贸d艂owych dostarczaj膮cych dane o klientach, w EDW b臋dzie jedna tabela KLIENT, z jednym rekordem dla ka偶dego klienta - nawet je偶eli ten klient istnieje w ka偶dym z pi臋tnastu system贸w 藕r贸d艂owych.
Jak si臋 to odbywa?
Uwa偶ny Czytelnik zapewne ju偶 si臋 domy艣li艂: identyfikator unikalny zosta艂 ju偶 wygenerowany i czeka grzecznie w warstwie XREF. Jedyne, co trzeba teraz zrobi膰, to wykona膰 operacj臋 MERGE (a wi臋c: zaktualizowa膰 rekordy istniej膮ce oraz dopisa膰 nowe, u偶ywaj膮c numerycznej kolumny ID z warstwy XREF).
Je偶eli dane pochodz膮 tylko z jednego systemu 藕r贸d艂owego, warstwy Landing i XREF dla danej encji s膮 pomijane i identyfikator generujemy bezpo艣rednio w EDW, u偶ywaj膮c kluczy biznesowych wzi臋tych z warstwy Stage.
Jak sobie niejasno przypominamy, przy wype艂nianiu danymi warstwy XREF pomin臋li艣my jeden istotny szczeg贸艂, kt贸ry mieli艣my sobie om贸wi膰 przy okazji warstwy EDW. Tym "drobiazgiem" jest spos贸b, w jaki generujemy identyfikatory rekord贸w w XREF. Ot贸偶 zanim wygenerujemy NOWE warto艣ci ID dla rekord贸w, kt贸rych jeszcze nie ma w EDW, musimy najpierw skopiowa膰 warto艣ci ID ISTNIEJ膭CE ju偶 w EDW. W tym celu wykonujemy JOIN mi臋dzy warstwami XREF i EDW, po kluczu biznesowym (poniewa偶 to jest jedyny klucz, na podstawie kt贸rego mo偶emy stwierdzi膰, 偶e dany rekord ju偶 istnieje w EDW).
Przyk艂ad:
Dajmy na to, 偶e w EDW mamy tabel臋 KLIENT z jednym rekordem:
ID, NAZWISKO, IMIE, DATA_URODZENIA, NR_VAT
1, Kowalski, Adam, 1963/04/14, AA923875
Dajmy na to, 偶e w tabeli L_KLIENT (warstwa Landing) mamy trzy rekordy:
NR_VAT, NAZWISKO, IMIE, DATA_URODZENIA, CRM_ID, CRM_NAME, CRM_SURNAME, CRM_VAT_NO, CRM_BIRTHDATE, FIKS_ID, FIKS_NAZWISKO, FIKS_IMIE, FIKS_NUMER_VAT, SRC_SYSTEM_CODE, SRC_SYSTEM_ID
AA923875,Kowalski,Adam,19630414,28346,Kowalski,Adam,AA923875,19630414,NULL,NULL,NULL,NULL,CRM,1
AA923875,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,837465,Kowalski,Adam,AA923875,FIKS,2
AB923498765,Malinowska,Anna,19531203,5234,Malinowska,Anna,AB923498765,19531203,NULL,NULL,NULL,NULL,CRM,1
Wida膰, 偶e Adam Kowalski zosta艂 nam podes艂any zar贸wno z CRM-u jak te偶 s FIKS-a. Ale Adama Kowalskiego ju偶 mamy w EDW, pod tym rekordem:
ID,NR_VAT, NAZWISKO, IMIE, DATA_URODZENIA,SRC_SYSTEM
17,AA923875,Kowlaski,Adam,19630414,3
Niestety, jak wida膰, w nazwisku Adama mamy w EDW liter贸wk臋 ("Kowlaski zamiast "Kowalski").
艁aduj膮c dane z Landing do XREF sprawdzimy, czy klient o numerze VAT = "AA923875" ju偶 istnieje w EDW i - je偶eli tak - przepiszemy jego ID=17 do XREF, zar贸wno do rekordu pochodz膮cego z CRM, jak te偶 do rekordu pochodz膮cego z FIKS. A wi臋c dane Adama w XREF b臋d膮 wygl膮da艂y o, tak:
ID, NR_VAT, NAZWISKO, IMIE, DATA_URODZENIA, CRM_ID, CRM_NAME, CRM_SURNAME, CRM_VAT_NO, CRM_BIRTHDATE, FIKS_ID, FIKS_NAZWISKO, FIKS_IMIE, FIKS_NUMER_VAT, SRC_SYSTEM_CODE, SRC_SYSTEM_ID
17,AA923875,Kowalski,Adam,19630414,28346,Kowalski,Adam,AA923875,19630414,NULL,NULL,NULL,NULL,CRM,1
17,AA923875,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,837465,Kowalski,Adam,AA923875,FIKS,2
Za艂贸偶my, 偶e Anna Malinowska w EDW jeszcze nie istnieje (sprawdzone po VAT_NO, kt贸ry jest kluczem biznesowym) - zostanie wi臋c dla niej wygenerowany nowy, unikalny identyfikator ID=983274, kt贸ry trafi do XREF:
ID, NR_VAT, NAZWISKO, IMIE, DATA_URODZENIA, CRM_ID, CRM_NAME, CRM_SURNAME, CRM_VAT_NO, CRM_BIRTHDATE, FIKS_ID, FIKS_NAZWISKO, FIKS_IMIE, FIKS_NUMER_VAT, SRC_SYSTEM_CODE, SRC_SYSTEM_ID
983274,AB923498765,Malinowska,Anna,19531203,5234,Malinowska,Anna,AB923498765,19531203,NULL,NULL,NULL,NULL,CRM,1
OK, mamy wi臋c dane w warstwie XREF (tym razem za艂adowane poprawnie i kompletnie), teraz zgrywamy je, najlepiej operatorem MERGE, do warstwy EDW:
MERGE KLIENT TGT
USING (
SELECT ID
, NR_VAT
, MAX(NAZWISKO) NAZWISKO
, MAX(IMIE) IMIE
, MAX(DATA_URODZENIA) DATA_URODZENIA
, SUM(SRC_SYSTEM_ID) SOURCE_SYSTEMS
FROM X_KLIENT
GROUP BY ID, NR_VAT
)聽 SRC
ON TGT.ID=SRC.ID
WHEN MATCHED THEN UPDATE SET
TGT.NAZWISKO = SRC.NAZWISKO
, TGT.IMIE=SRC.IMIE
, TGT.DATA_URODZENIA = SRC.DATA_URODZENIA
, TGT.SOURCE_SYSTEMS = SRC.SOURCE_SYSTEMS
WHEN NOT MATCHED BY TARGET THEN INSERT VALUES (
SRC.ID
, SRC.NR_VAT
, SRC.NAZWISKO
, SRC.IMIE
, SRC.DATA_URODZENIA
, SRC.SOURCE_SYSTEMS
)
Wszystko 艂adnie i pi臋knie, z jednym wyj膮tkiem: w powy偶szym zapytaniu ca艂kowicie pomijamy priorytety system贸w 藕r贸d艂owych i 艂adujemy wszystkie atrybuty jak leci, agreguj膮c je za pomoc膮 operatora MAX(). W ten spos贸b wprawdzie dane faktycznie trafi膮 do EDW (i poprawimy liter贸wk臋, o ile zosta艂a ona poprawiona w systemie 藕r贸d艂owym), jednak rozwi膮zanie jest jeszcze niekompletne. Zamiast bowiem agregacji atrybut贸w mi臋dzy XREF a EDW powinni艣my wzi膮膰 pod uwag臋 priorytety system贸w 藕r贸d艂owych i za艂adowa膰 konkretne warto艣ci, a nie wyniki agregacji.
Ale o tym ju偶 w nast臋pnym odcinku, 偶eby nie wrzuca膰 wszystkiego do jednego garnka, bo zamiast smacznej i po偶ywnej zupy wyjdzie nam niestrawna breja.
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.