RAPORTY JAK SKALOWAĆ, OD JEDNEGO DO WIELU, CZYLI CO MANAGER MOŻE WYMYŚLIĆ NA PRZYKŁADZIE BAZY RAPORTUJĄCEJ Z VERSIONONE. Jacek Jagieła jacek.jagiela@gmail.com 4Developers, Warszawa 7.04.2013
Kiedy przychodzi szef i nie jest zadowolony z raportów wbudowanych, czyli historia o tym gdzie wyświetlić dane dla szefa. Możliwości od Excel przez Crystal Report
VersionOne Agile Product Lifecycle Management http://www.versionone.com/
Raporty wbudowane Ponad 60 raportow Mierzenie każdej metryki Agile Dowolnie konfigurowalne Wykresy Bardzo ciekawa grafika
ZA MAŁO????? Nasz szef nie umie posługiwać się narzędziem Nie rozumie metryk Szuka dla nas zajęcia
Projekty Software Hardware Components VersionOne Bledy z pola
Od czego zacząć? Excel Można wrzucić dane zbierając z różnych źródeł Podłączyć do Excela zewnętrzne źródło
Znamy SQLa... WITH sales_numbers AS ( SELECT s.prod_id, s.amount_sold, t.week_ending_day FROM sales s, times t, products p WHERE s.time_id = t.time_id AND s.prod_id = p.prod_id AND p.prod_category = 'Photo' AND p.prod_name LIKE '%Memory%' AND t.week_ending_day BETWEEN TO_DATE('01-JUL-2001','dd-MON-yyyy') AND TO_DATE('16-JUL-2001','dd-MON-yyyy') ), product_revenue AS ( SELECT p.prod_name product, s.week_ending_day, SUM(s.amount_sold) revenue FROM products p LEFT OUTER JOIN ( SELECT prod_id, amount_sold, week_ending_day FROM sales_numbers) s ON (s.prod_id = p.prod_id) WHERE p.prod_category = 'Photo' AND p.prod_name LIKE '%Memory%' GROUP BY p.prod_name, s.week_ending_day ), weeks AS ( SELECT distinct week_ending_day week FROM times WHERE week_ending_day BETWEEN TO_DATE('01-JUL- 2001','dd-MON-yyyy') AND TO_DATE('16-JUL-2001','dd-MON-yyyy') ), complete_product_revenue AS ( SELECT w.week, pr.product, nvl(pr.revenue,0) revenue FROM product_revenue pr PARTITION BY (product) RIGHT OUTER JOIN weeks w ON (w.week = pr.week_ending_day) )
Minusy Excella Brak elastyczności każda zmiana nowe query Dynamiczne dane (plus i minus) Brak odwołań do opisywanych systemów Udostępnianie danych rozsyłanie dokumentu w świat Różni menadżerowie mają różną wiedzę z Excela Poprawianie błędów zgłoszonych przez użytkownika końcowego
Tworzymy bazę raportującą Nowa baza? Dodawać tabele? Kupić narzędzie Zlecić to komuś Korzystamy z istniejącej Może wystarczą kwerendy Na pewno jest jakiś OpenSource
Zaczynamy tworzyć Bazę Raportową Silnik? Nowy/Istniejący Łączność do bazy produkcyjnej Konwencja nazewnicza Integralność danych Dowolny Dowolny Zaczynamy od LINKU do samego siebie Stała i niezależna od systemu Szukamy PK
Architektura
Pierwsze kroki Database LINK CREATE DATABASE LINK local CONNECT TO hr IDENTIFIED BY password USING 'local';
SYNONYMS Nasz główny przyjaciel Używajmy we wszystkich Query Można zmieniać wskazania dynamicznie Czasem wykorzystywane w backupach i importach danych
VIEW Definiujmy często Duże bloki SQLa wykorzystywane w wielu miejscach zastępujemy widokami Używamy również do wprowadzania danych Pozwalają skrócić import danych
MATERIALIZED VIEWS Kiedy VIEW wykonuje się za długo Problem z szybkim odświeżaniem Korzystać można tak długo aż odświeżanie nie będzie problemem
FUNCTION Każdy duży blok w query można zastąpić funkcja Funkcje moga zwracać obiekty niekoniecznie tylko dane
PROCEDURE Używane przede wszystkim do wykonywania bloków przygotowujące dane Dobrze miec procedure dla każdego obszaru
PACKAGE Każda grupa raportów posiadała swój pakiet Dobre miejsce do pisania interfejsow do komunikacji. Zasada lepiej dodać niż zmieniać. Można tworzyć w pakiecie wiele funkcji o podobnej funkcjonalności ale innym wywołaniu.
Tworzymy Bazę dla VersionOne
Struktura w VersionOne
Co bierzemy? Faza I PrimaryWorkitem calość z historia Epic stan aktualny Timebox stan aktualny Scope stan aktualny Schedule stan aktualny
ETL Własna implementacja w C# Pobiera XMLe za pomocą protokołu Dane Historyczne https://www9.v1host.com/lumesse/rest- 1.v1/Hist/Story/1063?sel=Key,Scope.Name,Name,Number Aktualne https://www9.v1host.com/lumesse/rest-1.v1/data/scope?sel=name,createdate,key Wprowadza recordy do Tabel Źródeł PK = Key + CreateDate
Tabele Źródeł Source stała dla każdego źródła V1 ID oparta o sekwencje unikalna w bazie raportujacej Key PK z VersionOne. Jest to PK dla aktualnych danych CreateDate data utworzenia z VersionOne PK = Source + Key + CreateDate
Procedura UpdateBazy Backup istniejacych danych Create TABLE t1_bck AS Select * From t1; Przełączenie Synonyms na backup Truncate Table t1; Insert into t1 Select * from vw_t1; Przełączenie Synonyms na tabele raportowe UpdateBazy uruchamiany tylko 3 razy na dobe
Wyswietlanie Raportów Dynamiczna strona www napisana w C# Każdy raport miał swoją procedurę, w której było ogromne SQL query Dużo powtarzającego się kodu
Problemy Tłumaczenie PK VersionOne na ID w bazie raportującej szukanie błędów Zbyt długie odstępy między aktualizacjami Niektóre zdarzenia nie zarajestrowały się w bazie Brak gwarancji spójności danych Za mała modularyzacja
Schemat podstawy
Co bierzemy? Faza II PrimaryWorkitem calość z historia Epic całość z historią Timebox całość z historią Scope całość z historią Schedule całość z historią
ETL - zmiany Pobiera XMLe za pomocą protokołu Dane Historyczne https://www9.v1host.com/lumesse/rest- 1.v1/Hist/Story/1063?sel=Key,Scope.Name,Name,Number Użycie PK z VersionOne: Key + Moment Import Key > LastKey AND Moment >= LastMoment
Tabele Źródeł Source stała dla każdego źródła V1 PK = Source + Key + Moment
Procedura UpdateBazy UpdateBazy uruchamiany co 3 minuty Begin Transaction Aktualizacja tylko małej ilości rekordów Merge Table zamiast Insert
Korzyści Łatwość utrzymania spójności VersionOne z bazą raportową. Aktualizacje praktycznie Online Zminimalizowanie ilości danych do aktualizacji Podnoszenie modularyzacji
Jak to właściwie działało? Key Moment Number Name CreateDate 1063 1064 B-01001 Sample: Logon 02-01-12 1063 1132 B-01001 Sample: Logon 04-03-13 1063 1252 B-01001 Sample: Logon 10-05-12 1063 1281 B-01001 Sample: Logon 11-07-12 1063 1325 B-01001 Sample: Logon 15-08-12 Source Key Moment Number Name StartDate EndDate V1 1063 1064 B-01001 Sample: Logon 02-01-12 04-03-13 V1 1063 1132 B-01001 Sample: Logon 04-03-13 10-05-12 V1 1063 1252 B-01001 Sample: Logon 10-05-12 11-07-12 V1 1063 1281 B-01001 Sample: Logon 11-07-12 15-08-12 V1 1063 1325 B-01001 Sample: Logon 15-08-12
Nowe dane Key Moment Number Name CreateDate 1063 1064 B-01001 Sample: Logon 02-01-12 1063 1132 B-01001 Sample: Logon 04-03-13 1063 1252 B-01001 Sample: Logon 10-05-12 1063 1281 B-01001 Sample: Logon 11-07-12 1063 1325 B-01001 Sample: Logon 15-08-12 1063 1328 B-01001 Sample: Logon 22-08-12 Source Key Moment Number Name StartDate EndDate V1 1063 1064 B-01001 Sample: Logon 02-01-12 04-03-13 V1 1063 1132 B-01001 Sample: Logon 04-03-13 10-05-12 V1 1063 1252 B-01001 Sample: Logon 10-05-12 11-07-12 V1 1063 1281 B-01001 Sample: Logon 11-07-12 15-08-12 V1 1063 1325 B-01001 Sample: Logon 15-08-12 22-08-12 V1 1063 1405 B-01001 Sample: Logon 22-08-12
FROM S_Story st, S_Scope sc... WHERE st.moment > (Select MAX(Moment) FROM StoryScope)
Co z danymi z rekordu wyżej? SELECT... LAG(CreateDate, 1, 0) OVER (PARTITION BY Key ORDER BY Moment) AS enddate
MERGE INTO StoryWeekTable D USING ( SELECT Key,... FROM StoryWeekTable_VW ) S ON (D.Key = S.Key) WHEN MATCHED THEN UPDATE SET D... = S... WHEN NOT MATCHED THEN INSERT (...) VALUES (...) ;
Wiele systemów
Epic z górnego poziomu WHERE... REGEXP_LIKE (feature_name, `^FR[0-9]+`)...
views StoryScope_VW StoryEpic_VW ScopeEpic_VW StoryWeek_VW StorySchedule_VW
Tworzenie Raportów - query SELECT col1, col2, col3 FROM tab1, tab2, tab3 WHERE tab1.col1 = tab2.col2;
Pipe Functions CREATE FUNCTION ReportScope( SPCF...) RETURN ScopeTableType PIPELINED IS out_rec ScopeType; in_rec ScopeTable%ROWTYPE; BEGIN LOOP FETCH ScopeTable INTO in_rec; EXIT WHEN p%notfound;... ScopeType.col1 := in_rec.col1; IF S in (`AA`, `BB`) THEN... END IF; PIPE ROW(out_rec); END LOOP; CLOSE ScopeTable; RETURN; END;
Co kiedy wydajność VIEW zaczyna się psuć Każde vw przepiszmy do mv lub tabeli Dokładamy dane tylko różnicowo Potrzebujemy kolejnych tabel i widoków pośrednich
Backlog w skali tygodnia Widok z wyrazeniem:... Trunc(CreateDate, `YY`), Trunc(CreateDate, `WW`)...
ETL komercyjne IBM Websphere DataStage (wcześniej Ascential DataStage i Ardent DataStage) Oracle Warehouse Builder Informatica PowerCenter Cognos Decisionstream Ab Initio BusinessObjects Data Integrator (BODI) Microsoft SQL Server Integration Services (SSIS) Pentaho Data Integration - Projekt Kettle (open source) SAS ETL studio
Systemy raportowania Crystal Report Reporting services DataVision