Tabele historyczne w PostgreSQL Rafał Piechocki Promet
Tabele historyczne wprowadzenie
Cele i korzyści
Cele i korzyści stosowania tabel historycznych Archiwum wersji Pomoc w sporze Śledzenie zmian Podstawowe PITR Backup danych Wyłapywanie błędów Dodatkowe
Realizacja tabel historycznych
Realizacja tabel historycznych Aplikacja ORM Baza danych Serwer bazy danych
Czynniki, które należy brać pod uwagę Wpływ na wydajność Przeźroczystość rozwiązania Łatwość dostępu do archiwum Łatwość implementacji
Przykładowe implementacje 1. Osobna tabela – change logi
Tabela podstawowa + tabela change logów ZDJECIE (tabela podstawowa) id pesel status komunikat pracownik 1 85050500007 Promet 2 (update) 87070700005 -1 Nie kolorowe CHANGE_LOG # tabela id data operacja 3 zdjecie 1 2012-04-01 insert 4 2 2012-12-08 update CHANGE_LOG_VALUE # kolumna stara nowa 4 status -1 komunikat Nie kolorowe pracownik Promet
INSERT INTO dz_oceny (os_id,toc_kod,wart_oc_kolejnosc,prot_id,term_prot_nr) VALUES ('5094','ZAL-STD','1','136651','1'); INSERT INTO M_CHANGE_LOG (TABLE_NAME, MOD_TIME, MOD_TYPE) VALUES ('dz_oceny', now(), 'insert'); SELECT MAX(id) as max FROM M_CHANGE_LOG; INSERT INTO M_CHANGE_LOG_VALUES (CHANGE_ID, FIELD_NAME, VALUE) VALUES (8044, 'os_id', '5094'); INSERT INTO M_CHANGE_LOG_VALUES (CHANGE_ID, FIELD_NAME, VALUE) VALUES (8044, 'toc_kod', 'ZAL-STD'); INSERT INTO M_CHANGE_LOG_VALUES (CHANGE_ID, FIELD_NAME, VALUE) VALUES (8044, 'wart_oc_kolejnosc', '1'); INSERT INTO M_CHANGE_LOG_VALUES (CHANGE_ID, FIELD_NAME, VALUE) VALUES (8044, 'prot_id', '136651'); INSERT INTO M_CHANGE_LOG_VALUES (CHANGE_ID, FIELD_NAME, VALUE) VALUES (8044, 'term_prot_nr', '1');
Tabele typu change log - podsumowanie Zalety: Łatwość wykrywania zmian Łatwość migracji danych Testowanie spójności danych Wady: Wydajność (liczba zapytań) Trudność implementacji Nieprzeźroczystość?
Przykładowe implementacje 2. Tabela + widok
Tabela + widok Filtr: WHERE waznosc=infinity ZDJECIE (tabela podstawowa) id waznosc pesel status komunikat pracownik 1 2012-04-08 85050500007 2012-04-15 -1 Nie kolorowe Promet 2012-08-07 infinity Zdjęcie OK 2 87070700007 Filtr: WHERE waznosc=infinity V_ZDJECIE (widok dla tabeli podstawowej) id waznosc pesel status komunikat pracownik 1 infinity 85050500007 Zdjęcie OK Promet 2 87070700007
Tabela podstawowa ZDJECIE (tabela podstawowa) id waznosc pesel status komunikat pracownik 1 2012-04-08 85050500007 2012-04-15 -1 Nie kolorowe Promet 2012-08-07 infinity Zdjęcie OK 2 87070700007 Tabela zawiera zarówno bieżące dane jak i archiwalne. Klucz główny: (ID + waznosc), ograniczenia (pesel + waznosc) Triggery INSERT, UPDATE, DELETE: Oznaczają bieżący rekord jako wygasły Wstawiają nowy rekord oznaczony jako ważny Chronią archiwalne dane przed zmianą
Widok dla tabeli podstawowej V_ZDJECIE (widok dla tabeli podstawowej) id waznosc pesel status komunikat pracownik 1 infinity 85050500007 Zdjęcie OK Promet 2 87070700007 Filtr wybiera z tabeli podstawowej wyłącznie te rekordy, które nie wygasły. Widok zawiera zatem wyłącznie bieżące dane. Możliwość wprowadzenia reguł dla widoku = możliwość wykonywania na widoku operacji: INSERT UPDATE DELETE
Demonstracja Tabela + widok
Tabela + widok - podsumowanie Zalety: Łatwy dostęp do archiwum Bezpieczeństwo danych Wady: Klucze główne, ograniczenia Rozmiar tabeli podstawowej Nienaturalne operacje Problematyczna zmiana struktury
Przykładowe implementacje 3. Tabela podstawowa + tabela archiwalna
Tabela podstawowa + tabela archiwalna PUBLIC.ZDJECIE (tabela podstawowa) id timestamp pesel status komunikat pracownik 1 2012-07-15 85050500007 Zdjęcie OK Promet 2 2012-08-08 87070700007 ARCHIWUM.ZDJECIE (tabela archiwalna) id timestamp pesel status komunikat pracownik 1 2012-04-08 85050500007 -1 Nie kolorowe Promet 2012-06-07 2012-07-15 Zdjęcie OK 2 2012-08-08 87070700007
Tabela podstawowa Zawiera wyłącznie aktualne dane PUBLIC.ZDJECIE (tabela podstawowa) id timestamp pesel status komunikat pracownik 1 2012-07-15 85050500007 Zdjęcie OK Promet 2 2012-08-08 87070700007 Zawiera wyłącznie aktualne dane Triggery INSERT, DELETE, UPDATE kopiują dane do archiwum, nie zmieniając nic w tabeli podstawowej. Mogą dziedziczyć podstawową strukturę z szablonu
Tabela archiwalna Tabela znajduje się w osobnym schemacie DB ARCHIWUM.ZDJECIE (tabela archiwalna) id timestamp pesel status komunikat pracownik 1 2012-04-08 85050500007 -1 Nie kolorowe Promet 2012-06-07 2012-07-15 Zdjęcie OK 2 2012-08-08 87070700007 Tabela znajduje się w osobnym schemacie DB Zawiera dane archiwalne + dane bieżące Dane mogą być chronione przed zmianą/kasowaniem Schemat może być umieszczony na innym Storage-u
Tabela podstawowa + tabela archiwalna Wykorzystywane mechanizmy DBMS: Dziedziczenie struktury Triggery Procedury składowane Rozwiązane problemy: Spójność struktury tabeli podstawowej z archiwalną Łatwość tworzenia tabel archiwalnych i potrzebnych triggerów
Dziedziczenie tabel Wzorzec (dla wszystkich tabel, które mają mieć archiwum) Tabela podstawowa Tabela archiwalna wskazuje jakie tabele mają być archiwizowane (opcjonalne) zapewnienie spójności struktury dla tabel (konieczne)
Tabela podstawowa + tabela archiwalna Demonstracja Tabela podstawowa + tabela archiwalna
Tabela podstawowa + tabela archiwalna Zalety: Łatwy dostęp do danych Dostosowanie się do zmian struktury Wydajność Przeźroczystość dla aplikacji Naturalne zapytania SQL Tabela archiwalna jako backup, PITR Wady: Implementacja w innych DBMS?
Kiedy stosować, a kiedy nie?
Kiedy (nie) stosować? Warto stosować: Nie warto stosować: Kluczowe dane Nie warto stosować: Często zmieniające się dane Dane statyczne Dane wtórne/redundantne
Pytania?