Temporální databáze Martin Zikmund
Osnova Motivace Temporální databáze Standardizace Ukázka SQL:2011 Application-time period tables System-versioned tables Bitemporal tables Komerční implementace Shrnutí
Motivace Data s danou platností v čase Bez podpory v databáze Příklady Slevová akce v internetovém obchodě Předplatné služeb, prémiové členství Plánování vydání článků v systému pro správu obsahu Platy zaměstnanců
Co jsou temporální databáze? Databázový systém se zabudovanou podporou pro manipulaci s daty zohledňujícími čas
Co jsou temporální databáze? Klasická databáze Implementace v aplikačním kódu Složitější kontrola referenční integrity Složitější dotazování Temporální databáze Centralizace logiky v databázi Zjednodušení aplikačního kódu Transparentní přístup k datům
Standardizace 1992 Richard Snodgrass – první návrhy na vývoj rozšíření SQL pro temporální data
1993 Standardizace TSQL2 – rozšíření vzešlá z návrhů Prezentace výsledků skupině American National Standard for Database Language SQL
Standardizace 1994 Finální verze TSQL2 Language Specification
Standardizace 1999 Pokus o přidání TSQL2 jako součásti specifikace SQL:1999 (SQL3) Chris Date a Hugh Darwen – kritika přístupu TSQL2 Neúspěšné
Standardizace 2001 ISO (International Organization for Standardization) projekt pro standardizaci podpory temporálních dat v SQL zrušen
2011 Standardizace Standard SQL:2011 Part 2: SQL/Foundation Application-time period tables – valid-time tables System-versioned tables – transaction-time tables System-versioned application- time period tables – bitemporal tables
SQL:2011 Dimenze času Valid time Transaction time Období, ve kterém je fakt pravdivý Příklad: období, kdy má být článek zveřejněn na webu V SQL:2011 – application-time period Období, po které je fakt uložen v databázi Příklad: doba od chvíle, kdy autor článek dopíše a uloží do databáze V SQL:2011 – system-time period
SQL:2011 Perioda času Nutnost uložení časového úseku do database Nový datový typ? Nevýhodné z hlediska podpory Vysoká cena implementace Zahrnutí typu do všech nástrojů Zahrnutí podpory typu do JDBC, ODBC, .NET, … Zajištění podpory v jazycích Důsledek – pomalejší zavedení standardu v produkci a komerčních řešeních
SQL:2011 Perioda času startDate < endDate [startDate, endDate) Řešení – definice periody času pomocí metadat tabulky a existujících datových typů TIMESTAMP a DATE Dva sloupce v tabulce určují počátek a konec časové periody Implicitně omezení, že počátek periody je dříve než její konec Standard používá zleva uzavřený model časového intervalu startDate < endDate [startDate, endDate)
SQL:2011 Application-time period table Zachycení reality – fakta, která platí v nějakém období včetně minulosti a budoucnosti CREATE TABLE Employee ( Id INTEGER, JobStart DATE, JobEnd DATE, DepartmentId INTEGER, PERIOD FOR JobPeriod ( JobStart, JobEnd ) )
SQL:2011 Application-time INSERT Vkládání řádků – zahrnuje i data období platnosti řádku INSERT INTO Employee ( Id, JobStart, JobEnd, DepartmentId ) VALUES ( 1, DATE '2016-01-01', DATE '2016-05-20' , 1 )
SQL:2011 Application-time UPDATE Lze použít klasický Rozšíření FOR PORTION umožní změnit hodnoty sloupců pro určený časový úsek Id JobStart JobEnd DepartmentId 1 2016-01-01 2016-05-20 UPDATE Employee FOR PORTION OF JobPeriod FROM DATE '2016-02-01' TO DATE '2016-03-01' SET DepartmentId = 2 WHERE Id = 1 Id JobStart JobEnd DepartmentId 1 2016-01-01 2016-02-01 2016-03-01 2 2016-05-20
SQL:2011 Application-time Delete Lze použít klasický Rozšíření FOR PERIOD umožní mazat záznam pro určený časový úsek Id JobStart JobEnd DepartmentId 1 2016-01-01 2016-05-20 DELETE Employee FOR PORTION OF JobPeriod FROM DATE '2016-02-01' TO DATE '2016-03-01' WHERE Id = 1 Id JobStart JobEnd DepartmentId 1 2016-01-01 2016-02-01 2016-03-01 2016-05-20
SQL:2011 Application-time Id JobStart JobEnd DepartmentId 1 2016-01-01 2016-02-01 2016-03-01 2 2016-05-20 Co primární klíč?
SQL:2011 Application-time Primární klíče Sloupec Id jako primární klíč nestačí Řešení – primární klíč musí obsahovat i periodu Sloupce samotné nestačí – řádky by se mohly překrývat Rozšíření WITHOUT OVERLAPS toto omezení kontroluje Id JobStart JobEnd DepartmentId 1 2016-01-01 2016-02-01 2016-01-15 2016-03-01 2 ALTER TABLE Employee ADD PRIMARY KEY ( Id, JobPeriod WITHOUT OVERLAPS )
SQL:2011 Application-time Referenční Integrita Přidejme druhou tabulku – oddělení CREATE TABLE Department ( Id INTEGER, ActiveStart DATE, ActiveEnd DATE, Name VARCHAR(20), PERIOD FOR ActivePeriod ( ActiveStart, ActiveEnd ), PRIMARY KEY ( Id, ActivePeriod WITHOUT OVERLAPS ) )
SQL:2011 Application-time Referenční Integrita Zaměstnanci mohou pracovat pouze v odděleních, která jsou aktivní EMPLOYEE DEPARTMENT Id JobStart JobEnd DepartmentId 1 2015-01-01 2016-03-01 2017-12-01 2 Id ActiveStart ActiveEnd Name 1 2010-11-08 2016-04-01 Phone marketing 2 2015-08-01 2016-12-24 Enterprise marketing 2020-12-31 Business marketing ALTER TABLE Employee ADD FOREIGN KEY ( DepartmentId, PERIOD JobPeriod ) REFERENCES Department ( Id, PERIOD ActivePeriod ) Bere v úvahu i sjednocení časových intervalů
SQL:2011 Application-time DOTAZování Základní přístup – klasické dotazy SELECT Name FROM Department WHERE Id = 1 AND ActiveStart <= DATE '2016-01-01' AND ActiveEnd > DATE '2016-01-01' Rozšíření pro dotazování – CONTAINS, OVERLAPS, EQUALS, PRECEDES, SUCCEEDS, IMMEDIATELY PRECEDES, IMMEDIATELY SUCCEEDS
SQL:2011 Application-time DOTAZování SELECT Name FROM Department WHERE Id = 1 AND ActivePeriod CONTAINS DATE '2016-01-01' SELECT Name FROM Department WHERE Id = 1 AND ActivePeriod OVERLAPS PERIOD ( DATE '2016-01-01', DATE '2016-06-01' )
SQL:2011 System-versioned tables Udržování kompletní historie změn v databázi Často potřebné Změny objednávek Pohyby na účtu Požadováno zákonem Zachovat původní stav řádků i odstraněné řádky – řízeno databází Řešení – systém-versioned tables Koncept periody stejný
SQL:2011 System-versioned TABLE CREATE TABLE Employee ( Id Integer, SystemStart TIMESTAMP(12) GENERATED ALWAYS AS ROW START, SystemEnd TIMESTAMP(12) GENERATED ALWAYS AS ROW END, Name VARCHAR(30), PERIOD FOR SYSTEM_TIME (SystemStart, SystemEnd) ) WITH SYSTEM VERSIONING Současná systémová řádka – perioda systémového času pro řádku obsahuje aktuální systémový čas Historická systémová rádka – ostatní řádky Hodnoty SystemStart a SystemEnd – přiřazeny databází Název periody SYSTEM_TIME daný, nelze změnit Nelze měnit zpětně historické řádky
SQL:2011 System-versioned INSERT, UPDATE INSERT – automaticky nastavuje hodnotu SystemStart na časovou známku transakce a SystemEnd na nejvyšší hodnotu datového typu UPDATE – operuje pouze na aktuálních systémových řádkách – automaticky vkládajá historické řádky, nespouští triggery Id SystemStart SystemEnd Name 1 2016-01-01 9999-12-31 Hannah Oak UPDATE Employee SET Name = 'Hannah Winter' WHERE Id = 1 Id JobStart JobEnd Name 1 2016-01-01 2016-06-01 Hannah Oak 9999-12-31 Hannah Winter
SQL:2011 System-versioned DELETE DELETE – operuje pouze na aktuálních systémových řádkách, řádek nemaže, nespouští trigger Id SystemStart SystemEnd Name 1 2016-01-01 9999-12-31 Hannah Oak DELETE FROM Employee WHERE Id = 1 Id JobStart JobEnd Name 1 2016-01-01 2016-11-25 Hannah Oak
SQL:2011 System-versioned Primární klíč Omezení musí platit pouze pro současné řádky, historické pouze pro evidenci Jako primární klíč stačí Id ALTER TABLE Employee ADD PRIMARY KEY ( Id )
SQL:2011 System-versioned REFERENční integrita Omezení musí platit pouze pro současné řádky, historické pouze pro evidenci Jako cizí klíč stačí pouze odkaz na druhou tabulku ALTER TABLE Employee ADD FOREIGN KEY ( DepartmentId ) REFERENCES Department ( Id )
SQL:2011 System-versioned Dotazování Výchozí chování – pouze současné řádky – zpětná kompatibilita Id JobStart JobEnd Name 1 2016-01-01 2016-06-01 Hannah Oak 9999-12-31 Hannah Winter SELECT Name FROM Employee WHERE Id = 1 'Hannah Winter'
SQL:2011 System-versioned Dotazování SELECT Name FROM Employee FOR SYSTEM_TIME AS OF TIMESTAMP '2016- 01-15 00:00:00' Vrací jména, která byla v databázi platná o půlnoci 15. 1. 2016
SQL:2011 System-versioned Dotazování SELECT Id, Name FROM Employee FOR SYSTEM_TIME FROM TIMESTAMP '2016-01- 15 00:00:00' TO TIMESTAMP '2016-02-15 00:00:00' ID a jména, která byla v databázi platná od půlnoci 15. 1. 2016 do půlnoci 15. 2. 2016 (vyjma) Closed-open interval
SQL:2011 System-versioned Dotazování SELECT Id, Name FROM Employee FOR SYSTEM_TIME BETWEEN TIMESTAMP '2016- 01-15 00:00:00' AND TIMESTAMP '2016-02-15 00:00:00' ID a jména, která byla v databázi platná od půlnoci 15. 1. 2016 do půlnoci 15. 2. 2016 (včetně) Closed-closed interval
SQL:2011 Bitemporal tables Application-time i system-time tabulka současně CREATE TABLE Employee ( Id Integer, Name VARCHAR(30), JobStart DATE, JobEnd DATE, PERIOD FOR JobPeriod ( JobStart, JobEnd ), SystemStart TIMESTAMP(12) GENERATED ALWAYS AS ROW START, SystemEnd TIMESTAMP(12) GENERATED ALWAYS AS ROW END, PERIOD FOR SYSTEM_TIME (SystemStart, SystemEnd), PRIMARY KEY ( Id, JobPeriod WITHOUT OVERLAPS ) FOREIGN KEY ( DepartmentId, PERIOD JobPeriod ) REFERENCES Department ( Id, PERIOD ActivePeriod ) ) WITH SYSTEM VERSIONING
SQL:2011 Bitemporal tables Udržují nejen informaci o čase faktů v reálném světě, ale i o čase kdy se fakta projevila v databázi Příklad Změna jména – platná počínaje daným datem Do databáze zaznamenána později nebo dříve Je možné dohledat oba údaje Dotazy mohou brát v úvahu obě dimenze SELECT DepartmentId FROM Employee FOR SYSTEM_TIME AS OF TIMESTAMP '2016-05-01 00:00:00' WHERE Id = 1 AND JobPeriod CONTAINS DATE '2016-12-01' Dotaz vrací ID pracoviště, kde měl pracovník 1 pracovat 1. prosince 2016 podle stavu databáze platného o půlnoci 1. května 2016
SQL:2011 Budoucnost Návrhy na rozšíření standardu Podpora více aplikačních period na jednu tabulku Normalizace period – vytvoření sémanticky minimální množiny řádek vzniklých kombinací řádek s překryvem nebo přímo navazujících se stejnými netemporálními hodnotami Dotazy s UNION, INTERSECT a EXCEPT, které pracují s periodami
Komerční implementace IBM DB2 Implementace application-time i system-time od verze 10 Velmi blízké standardu SQL:2011 Je možné označit sloupce s periodou jako implicitně skryté – ve výsledcích dotazů SELECT * sloupce nejsou uvedeny, nutnost explicitního vyžádání Historické řádky uloženy v separátní tabulce „history table“ Testy - práce s temporálními daty pomocí zabudovaných rozšíření je průměrně 1,5x rychlejší než manuální implementace pomocí triggerů a uložených procedur [Florian Künzner, Dušan Petković, 2015]
Komerční implementace Teradata Implementace application-time i system-time od verze 10 Velmi odlišná od standardu, podobná návrhu TSQL2 Datový typ PERIOD Speciální hodnota UNTIL_CHANGED jako „nekonečno“, pro konec periody Implicitní sloupce s periodou
Komerční implementace ORACLE Implementace application-time i system-time od verze 12c Poměrně podobná standardu System-time historické řádky ukládány do tzv. FLASHBACK ARCHIVE Implicitní i explicitní definice sloupců periody
Komerční implementace MICROSOFT SQL SERVER Implementace system-time od verze 2016 Odlišné od standardu
Shrnutí Temporální data Temporální databáze Komerční implementace Široké využití Velmi častý požadavek Temporální databáze Výrazné zjednodušení implementace Ověřené a otestované Standardizace Komerční implementace Postupně se rozšiřuje
Zdroje Temporal features in SQL:2011, Krishna Kularni, Jan-Eike Michels (IBM Corporation) Modern Temporal Data Models: Strengths and Weaknesses, Dušan Petković A Comparison of Different Forms of Temporal Data Management, Florian Künzner and Dušan Petković Temporal Data in Relational Database Systems: A Comparison, Dušan Petković [online] https://en.wikipedia.org/wiki/Temporal_database