SlideShare a Scribd company logo
MariaDB Temporal Tables
Federico Razzoli
$ whoami
Hi, I’m Federico Razzoli from Vettabase Ltd
Database consultant, open source supporter,
long time MariaDB and MySQL user
● vettabase.com
● Federico-Razzoli.com
Temporal Tables Implementations
Proprietary DBMSs
● Oracle 11g (2007)
● Db2 (2012)
● SQL Server 2016
● Snowflake
In Db2, a temporal table can use system-period or application-period
Open source databases
● PostgreSQL has a temporal_tables extension
○ not available from the main cloud vendors
● CockroachDB
○ with limitations
● CruxDB (NoSQL)
● HBase stores old row versions and you can retrieve them
MariaDB
MariaDB supports both types of Temporal Tables:
● MariaDB 10.3: system_time
● MariaDB 10.4: application_time
Tables are bitemporal
Application Time
Example
CREATE OR REPLACE TABLE ticket (
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
state ENUM('OPEN', 'VERIFIED', 'FIXED', 'INVALID') NOT NULL
DEFAULT 'OPEN',
summary VARCHAR(200) NOT NULL,
description TEXT NOT NULL
)
ENGINE InnoDB
;
● We want to start to track changes to bugs over time
Making the table Application-Timed
ALTER TABLE ticket
LOCK = SHARED,
ALGORITHM = COPY,
ADD COLUMN valid_from DATETIME NOT NULL,
ADD COLUMN valid_to DATETIME NOT NULL,
ADD PERIOD FOR time_period (valid_from, valid_to) ;
We can use...
● Any temporal data type that includes a date (DATE, DATETIME, TIMESTAMP)
● Any storage engine
Inserting rows
MariaDB [test]> INSERT INTO ticket (summary, description) VALUES
-> ('I cannot login', 'Why is this happening to me?');
ERROR 1364 (HY000): Field 'valid_from' doesn't have a default value
MariaDB [test]> INSERT INTO ticket (summary, description,valid_from, valid_to)
VALUES
-> ('I cannot login', 'Why is this happening to me?',
-> '1994-01-01', '2010-01-01');
Query OK, 1 row affected (0.003 sec)
A better Application-Timed table
CREATE TABLE ticket_tmp LIKE ticket;
ALTER TABLE ticket_tmp
ADD COLUMN valid_from DATETIME NOT NULL
DEFAULT NOW(),
ADD COLUMN valid_to DATETIME NOT NULL
DEFAULT '2038-01-19 03:14:07.999999' ,
ADD INDEX idx_valid_from (valid_from),
ADD INDEX idx_valid_to (valid_to),
ADD PERIOD FOR time_period(valid_from, valid_to);
A better Application-Timed table
ALTER TABLE ticket_tmp
DROP PRIMARY KEY,
ADD PRIMARY KEY (id, valid_to)
;
-- populate the table
RENAME TABLE ticket TO ticket_old, ticket_tmp TO ticket;
● You will need to do similar operations with UNIQUE indexes
● RENAME TABLE is an atomic operation
Reading rows
MariaDB [test]> SELECT id, summary, valid_from, valid_to FROM ticket;
+----+----------------+---------------------+---------------------+
| id | summary | valid_from | valid_to |
+----+----------------+---------------------+---------------------+
| 1 | I cannot login | 1994-01-01 00:00:00 | 2010-01-01 00:00:00 |
+----+----------------+---------------------+---------------------+
1 row in set (0.001 sec)
MariaDB [test]> SELECT id, summary, valid_from, valid_to FROM ticket
-> WHERE NOW() BETWEEN valid_from AND valid_to;
Empty set (0.001 sec)
Deleting rows properly
CREATE OR REPLACE PROCEDURE ticket_delete(p_id INT)
MODIFIES SQL DATA
COMMENT 'Makes a row obsolete by changing its timestamp'
BEGIN
UPDATE ticket
SET valid_to = NOW()
WHERE id = p_id AND valid_to > NOW();
END;
Deleting rows properly
MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket WHERE id = 1;
+----+---------------------+---------------------+
| id | valid_from | valid_to |
+----+---------------------+---------------------+
| 1 | 2020-08-23 14:32:22 | 2038-01-19 03:14:07 |
+----+---------------------+---------------------+
MariaDB [test]> CALL ticket_delete(1);
MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket WHERE id = 1;
+----+---------------------+---------------------+
| id | valid_from | valid_to |
+----+---------------------+---------------------+
| 1 | 2020-08-23 14:32:22 | 2020-08-23 14:32:34 |
+----+---------------------+---------------------+
Deleting/updating periods
MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket;
+----+---------------------+---------------------+
| id | valid_from | valid_to |
+----+---------------------+---------------------+
| 1 | 1994-01-01 00:00:00 | 2010-01-01 00:00:00 |
+----+---------------------+---------------------+
MariaDB [test]> DELETE FROM ticket
-> FOR PORTION OF time_period FROM '1990-01-01' TO '2000-01-01'
-> WHERE id = 1;
MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket;
+----+---------------------+---------------------+
| id | valid_from | valid_to |
+----+---------------------+---------------------+
| 2 | 2000-01-01 00:00:00 | 2010-01-01 00:00:00 |
+----+---------------------+---------------------+
System Versioning
Back to our example...
CREATE OR REPLACE TABLE ticket (
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
state ENUM('OPEN', 'VERIFIED', 'FIXED', 'INVALID') NOT NULL
DEFAULT 'OPEN',
summary VARCHAR(200) NOT NULL,
description TEXT NOT NULL
)
ENGINE InnoDB
;
Making the table System-Versioned
ALTER TABLE ticket
LOCK = SHARED,
ALGORITHM = COPY,
ADD SYSTEM VERSIONING;
Making the table System-Versioned
ALTER TABLE ticket
LOCK = SHARED,
ALGORITHM = COPY,
ADD COLUMN inserted_at TIMESTAMP(6) GENERATED ALWAYS AS ROW START INVISIBLE,
ADD COLUMN deleted_at TIMESTAMP(6) GENERATED ALWAYS AS ROW END INVISIBLE,
ADD PERIOD FOR SYSTEM_TIME(inserted_at, deleted_at),
ADD SYSTEM VERSIONING;
Limitations:
● Temporal columns don’t have to be INVISIBLE, if they’re often needed
● MDEV-15968: System versioning and CONNECT engine don't work well
together: current data is not returned
● MDEV-17448: Support DATETIME(6) for ROW START, ROW END
Querying a Sysver Table
-- get current version of the rows
-- without the temporal columns (they’re INVISIBLE)
SELECT * FROM ticket;
-- get current version of the rows
-- with the temporal columns
SELECT *, inserted_at, deleted_at FROM ticket;
-- all current and old data
SELECT *, inserted_at, deleted_at
FROM ticket FOR SYSTEM_TIME ALL;
Get old versions of the rows
-- get deleted rows
SELECT *, inserted_at, deleted_at
FROM ticket FOR SYSTEM_TIME
FROM '1970-00-00' TO NOW() - 1 MICROSECOND;
SELECT *, inserted_at, deleted_at
FROM ticket FOR SYSTEM_TIME
BETWEEN '1970-00-00' AND NOW() - 1 MICROSECOND;
SELECT *, inserted_at, deleted_at
FROM ticket FOR SYSTEM_TIME ALL
WHERE deleted_at < NOW();
History of a row
SELECT id, state, inserted_at, deleted_at
FROM ticket FOR SYSTEM_TIME ALL
WHERE id = 3
ORDER BY deleted_at;
Read a row from a specific point in time
SELECT id, state
FROM ticket FOR SYSTEM_TIME AS OF TIMESTAMP'2020-08-22 08:52:36'
WHERE id = 3;
SELECT id, state
FROM ticket FOR SYSTEM_TIME ALL
WHERE id = 3 AND
'2020-08-22 08:52:36' BETWEEN inserted_at AND deleted_at;
Temporal JOINs
-- rows that were present on 07/01
-- whose state did not change after one month
SELECT t1.id, t1.inserted_at, t1.deleted_at
FROM ticket FOR SYSTEM_TIME ALL AS t1
LEFT JOIN ticket FOR SYSTEM_TIME ALL AS t2
ON
t1.id = t2.id
AND t1.state = t2.state
WHERE
'2020-07-01 00:00:00' BETWEEN t1.inserted_at AND t1.deleted_at
AND '2020-08-01 00:00:00' BETWEEN t2.inserted_at AND t2.deleted_at
AND t2.id IS NULL
ORDER BY t1.id;
Indexes
The ROW END column is automatically appended to:
● The Primary Key;
● All UNIQUE indexes.
Queries can use a whole index of its leftmost part,
so once a regular table becomes System Versioned queries performance will not
degrade.
For Application Timed tables, indexes remain unchanged.
The power of [bi]Temporal Tables
Hints about things you can do
● A table can be both system-versioned and application-timed (bitemporal)
● Stats on added/deleted rows by year, month, weekday, day, daytime…
● Stats on rows lifetime
● Get rows that never changed
● Get rows that change too often, or change at “strange” times
● Examine history of a row to find problems
● ...
Hints about things that you should do
● PK should never change, or tracking rows history will be impossible
○ If necessary, use a trigger that throws an error if OLD.id != NEW.id
● Application Time tables: no hard deletions/updates
● If you have to drop a column, move it to a new table to avoid losing the history
● If you have to add a column that is not often read/written, consider putting it
into a new table
● If you run stats or complex queries involving temporal columns, add
PERSISTENT columns and indexes on them to make queries faster
What we left out
This was a short introductory session, so we left out some features:
● ALTER TABLEs
○ They may erase or change parts of the history, so they’re disabled by default
● Partitioning
○ You can record the history in a separate partition, or multiple partitions
● Backups
○ Check the docs for problems with Sysver Tables and mysqldump
● Replication / binlog
○ Check the documentation for possible problems with Sysver Tables
○ MariaDB can be a replica of a MySQL server, and make use of Temporal Tables to
let analysts run certain analyses that they couldn’t run on MySQL
Thanks for attending!
Question time :-)

More Related Content

PDF
MariaDB Temporal Tables
PPTX
Scylla Summit 2022: Scylla 5.0 New Features, Part 1
PPTX
An Introduction to MongoDB Ops Manager
PPTX
MongoDB Sharding
PDF
My first 90 days with ClickHouse.pdf
PDF
Real time analytics at uber @ strata data 2019
PDF
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...
PPTX
Scylla on Kubernetes: Introducing the Scylla Operator
MariaDB Temporal Tables
Scylla Summit 2022: Scylla 5.0 New Features, Part 1
An Introduction to MongoDB Ops Manager
MongoDB Sharding
My first 90 days with ClickHouse.pdf
Real time analytics at uber @ strata data 2019
Streaming Data Lakes using Kafka Connect + Apache Hudi | Vinoth Chandar, Apac...
Scylla on Kubernetes: Introducing the Scylla Operator

What's hot (20)

PDF
MongoDB World 2019: How Braze uses the MongoDB Aggregation Pipeline for Lean,...
PDF
10 Good Reasons to Use ClickHouse
PDF
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)
PPTX
Mongo DB 성능최적화 전략
PPTX
Leveraging Neo4j With Apache Spark
PDF
A Technical Introduction to WiredTiger
PDF
Apache Iceberg - A Table Format for Hige Analytic Datasets
PPTX
Sizing Your MongoDB Cluster
PPTX
Introduction to MongoDB
PPTX
Best Practices for Managing MongoDB with Ops Manager
PPTX
Introducing MongoDB Atlas
PPTX
Cache in API Gateway
PDF
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
PPTX
Hive + Tez: A Performance Deep Dive
PDF
Best Practices for ETL with Apache NiFi on Kubernetes - Albert Lewandowski, G...
PDF
MongoDB Database Replication
PDF
SQLAlchemy Core: An Introduction
PPTX
When to Use MongoDB
PPTX
Understanding REST APIs in 5 Simple Steps
PDF
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
MongoDB World 2019: How Braze uses the MongoDB Aggregation Pipeline for Lean,...
10 Good Reasons to Use ClickHouse
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)
Mongo DB 성능최적화 전략
Leveraging Neo4j With Apache Spark
A Technical Introduction to WiredTiger
Apache Iceberg - A Table Format for Hige Analytic Datasets
Sizing Your MongoDB Cluster
Introduction to MongoDB
Best Practices for Managing MongoDB with Ops Manager
Introducing MongoDB Atlas
Cache in API Gateway
[pgday.Seoul 2022] PostgreSQL구조 - 윤성재
Hive + Tez: A Performance Deep Dive
Best Practices for ETL with Apache NiFi on Kubernetes - Albert Lewandowski, G...
MongoDB Database Replication
SQLAlchemy Core: An Introduction
When to Use MongoDB
Understanding REST APIs in 5 Simple Steps
ClickHouse Query Performance Tips and Tricks, by Robert Hodges, Altinity CEO
Ad

Similar to MariaDB Temporal Tables (20)

PDF
M|18 Querying Data at a Previous Point in Time
PDF
Webinar - MariaDB Temporal Tables: a demonstration
PDF
Advanced MariaDB features that developers love.pdf
PDF
Tracking your data across the fourth dimension
PDF
MariaDB Server 10.3 - Temporale Daten und neues zur DB-Kompatibilität
PPTX
Discovering and querying temporal data
PDF
What's New in MariaDB Server 10.3
PDF
Track your data across the fourth dimension
PDF
When and Why to Use MariaDB: New Features in 10.0 to 10.5
PDF
What's new in MariaDB Platform X3
PDF
Modern solutions for modern database load: improvements in the latest MariaDB...
PPT
tempDB.ppt
PDF
MySQL 8.0: not only good, it’s GREAT! - PHP UK 2019
PDF
Tracking your data across the fourth dimension
PPTX
Back to the future - Temporal Table in SQL Server 2016
PDF
SQLSat462 Parma 2015
PDF
Temporal database
PPTX
sql_server_2016_history_tables
PDF
MariaDB workshop
PDF
Time Travelling With DB2 10 For zOS
M|18 Querying Data at a Previous Point in Time
Webinar - MariaDB Temporal Tables: a demonstration
Advanced MariaDB features that developers love.pdf
Tracking your data across the fourth dimension
MariaDB Server 10.3 - Temporale Daten und neues zur DB-Kompatibilität
Discovering and querying temporal data
What's New in MariaDB Server 10.3
Track your data across the fourth dimension
When and Why to Use MariaDB: New Features in 10.0 to 10.5
What's new in MariaDB Platform X3
Modern solutions for modern database load: improvements in the latest MariaDB...
tempDB.ppt
MySQL 8.0: not only good, it’s GREAT! - PHP UK 2019
Tracking your data across the fourth dimension
Back to the future - Temporal Table in SQL Server 2016
SQLSat462 Parma 2015
Temporal database
sql_server_2016_history_tables
MariaDB workshop
Time Travelling With DB2 10 For zOS
Ad

More from Federico Razzoli (20)

PDF
MariaDB Data Protection: Backup Strategies for the Real World
PDF
MariaDB/MySQL_: Developing Scalable Applications
PDF
Webinar: Designing a schema for a Data Warehouse
PDF
High-level architecture of a complete MariaDB deployment
PDF
Webinar - Unleash AI power with MySQL and MindsDB
PDF
MariaDB Security Best Practices
PDF
A first look at MariaDB 11.x features and ideas on how to use them
PDF
MariaDB stored procedures and why they should be improved
PDF
Webinar - Key Reasons to Upgrade to MySQL 8.0 or MariaDB 10.11
PDF
MariaDB 10.11 key features overview for DBAs
PDF
Recent MariaDB features to learn for a happy life
PDF
Automate MariaDB Galera clusters deployments with Ansible
PDF
Creating Vagrant development machines with MariaDB
PDF
MariaDB, MySQL and Ansible: automating database infrastructures
PDF
Playing with the CONNECT storage engine
PDF
Database Design most common pitfalls
PDF
MySQL and MariaDB Backups
PDF
JSON in MySQL and MariaDB Databases
PDF
How MySQL can boost (or kill) your application v2
PDF
MySQL Transaction Isolation Levels (lightning talk)
MariaDB Data Protection: Backup Strategies for the Real World
MariaDB/MySQL_: Developing Scalable Applications
Webinar: Designing a schema for a Data Warehouse
High-level architecture of a complete MariaDB deployment
Webinar - Unleash AI power with MySQL and MindsDB
MariaDB Security Best Practices
A first look at MariaDB 11.x features and ideas on how to use them
MariaDB stored procedures and why they should be improved
Webinar - Key Reasons to Upgrade to MySQL 8.0 or MariaDB 10.11
MariaDB 10.11 key features overview for DBAs
Recent MariaDB features to learn for a happy life
Automate MariaDB Galera clusters deployments with Ansible
Creating Vagrant development machines with MariaDB
MariaDB, MySQL and Ansible: automating database infrastructures
Playing with the CONNECT storage engine
Database Design most common pitfalls
MySQL and MariaDB Backups
JSON in MySQL and MariaDB Databases
How MySQL can boost (or kill) your application v2
MySQL Transaction Isolation Levels (lightning talk)

Recently uploaded (20)

PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
MYSQL Presentation for SQL database connectivity
PDF
cuic standard and advanced reporting.pdf
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
20250228 LYD VKU AI Blended-Learning.pptx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Chapter 3 Spatial Domain Image Processing.pdf
Understanding_Digital_Forensics_Presentation.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
NewMind AI Weekly Chronicles - August'25 Week I
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Per capita expenditure prediction using model stacking based on satellite ima...
Spectral efficient network and resource selection model in 5G networks
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
MYSQL Presentation for SQL database connectivity
cuic standard and advanced reporting.pdf
Advanced methodologies resolving dimensionality complications for autism neur...
Unlocking AI with Model Context Protocol (MCP)
Reach Out and Touch Someone: Haptics and Empathic Computing
Mobile App Security Testing_ A Comprehensive Guide.pdf

MariaDB Temporal Tables

  • 2. $ whoami Hi, I’m Federico Razzoli from Vettabase Ltd Database consultant, open source supporter, long time MariaDB and MySQL user ● vettabase.com ● Federico-Razzoli.com
  • 4. Proprietary DBMSs ● Oracle 11g (2007) ● Db2 (2012) ● SQL Server 2016 ● Snowflake In Db2, a temporal table can use system-period or application-period
  • 5. Open source databases ● PostgreSQL has a temporal_tables extension ○ not available from the main cloud vendors ● CockroachDB ○ with limitations ● CruxDB (NoSQL) ● HBase stores old row versions and you can retrieve them
  • 6. MariaDB MariaDB supports both types of Temporal Tables: ● MariaDB 10.3: system_time ● MariaDB 10.4: application_time Tables are bitemporal
  • 8. Example CREATE OR REPLACE TABLE ticket ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, state ENUM('OPEN', 'VERIFIED', 'FIXED', 'INVALID') NOT NULL DEFAULT 'OPEN', summary VARCHAR(200) NOT NULL, description TEXT NOT NULL ) ENGINE InnoDB ; ● We want to start to track changes to bugs over time
  • 9. Making the table Application-Timed ALTER TABLE ticket LOCK = SHARED, ALGORITHM = COPY, ADD COLUMN valid_from DATETIME NOT NULL, ADD COLUMN valid_to DATETIME NOT NULL, ADD PERIOD FOR time_period (valid_from, valid_to) ; We can use... ● Any temporal data type that includes a date (DATE, DATETIME, TIMESTAMP) ● Any storage engine
  • 10. Inserting rows MariaDB [test]> INSERT INTO ticket (summary, description) VALUES -> ('I cannot login', 'Why is this happening to me?'); ERROR 1364 (HY000): Field 'valid_from' doesn't have a default value MariaDB [test]> INSERT INTO ticket (summary, description,valid_from, valid_to) VALUES -> ('I cannot login', 'Why is this happening to me?', -> '1994-01-01', '2010-01-01'); Query OK, 1 row affected (0.003 sec)
  • 11. A better Application-Timed table CREATE TABLE ticket_tmp LIKE ticket; ALTER TABLE ticket_tmp ADD COLUMN valid_from DATETIME NOT NULL DEFAULT NOW(), ADD COLUMN valid_to DATETIME NOT NULL DEFAULT '2038-01-19 03:14:07.999999' , ADD INDEX idx_valid_from (valid_from), ADD INDEX idx_valid_to (valid_to), ADD PERIOD FOR time_period(valid_from, valid_to);
  • 12. A better Application-Timed table ALTER TABLE ticket_tmp DROP PRIMARY KEY, ADD PRIMARY KEY (id, valid_to) ; -- populate the table RENAME TABLE ticket TO ticket_old, ticket_tmp TO ticket; ● You will need to do similar operations with UNIQUE indexes ● RENAME TABLE is an atomic operation
  • 13. Reading rows MariaDB [test]> SELECT id, summary, valid_from, valid_to FROM ticket; +----+----------------+---------------------+---------------------+ | id | summary | valid_from | valid_to | +----+----------------+---------------------+---------------------+ | 1 | I cannot login | 1994-01-01 00:00:00 | 2010-01-01 00:00:00 | +----+----------------+---------------------+---------------------+ 1 row in set (0.001 sec) MariaDB [test]> SELECT id, summary, valid_from, valid_to FROM ticket -> WHERE NOW() BETWEEN valid_from AND valid_to; Empty set (0.001 sec)
  • 14. Deleting rows properly CREATE OR REPLACE PROCEDURE ticket_delete(p_id INT) MODIFIES SQL DATA COMMENT 'Makes a row obsolete by changing its timestamp' BEGIN UPDATE ticket SET valid_to = NOW() WHERE id = p_id AND valid_to > NOW(); END;
  • 15. Deleting rows properly MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket WHERE id = 1; +----+---------------------+---------------------+ | id | valid_from | valid_to | +----+---------------------+---------------------+ | 1 | 2020-08-23 14:32:22 | 2038-01-19 03:14:07 | +----+---------------------+---------------------+ MariaDB [test]> CALL ticket_delete(1); MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket WHERE id = 1; +----+---------------------+---------------------+ | id | valid_from | valid_to | +----+---------------------+---------------------+ | 1 | 2020-08-23 14:32:22 | 2020-08-23 14:32:34 | +----+---------------------+---------------------+
  • 16. Deleting/updating periods MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket; +----+---------------------+---------------------+ | id | valid_from | valid_to | +----+---------------------+---------------------+ | 1 | 1994-01-01 00:00:00 | 2010-01-01 00:00:00 | +----+---------------------+---------------------+ MariaDB [test]> DELETE FROM ticket -> FOR PORTION OF time_period FROM '1990-01-01' TO '2000-01-01' -> WHERE id = 1; MariaDB [test]> SELECT id, valid_from, valid_to FROM ticket; +----+---------------------+---------------------+ | id | valid_from | valid_to | +----+---------------------+---------------------+ | 2 | 2000-01-01 00:00:00 | 2010-01-01 00:00:00 | +----+---------------------+---------------------+
  • 18. Back to our example... CREATE OR REPLACE TABLE ticket ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT, state ENUM('OPEN', 'VERIFIED', 'FIXED', 'INVALID') NOT NULL DEFAULT 'OPEN', summary VARCHAR(200) NOT NULL, description TEXT NOT NULL ) ENGINE InnoDB ;
  • 19. Making the table System-Versioned ALTER TABLE ticket LOCK = SHARED, ALGORITHM = COPY, ADD SYSTEM VERSIONING;
  • 20. Making the table System-Versioned ALTER TABLE ticket LOCK = SHARED, ALGORITHM = COPY, ADD COLUMN inserted_at TIMESTAMP(6) GENERATED ALWAYS AS ROW START INVISIBLE, ADD COLUMN deleted_at TIMESTAMP(6) GENERATED ALWAYS AS ROW END INVISIBLE, ADD PERIOD FOR SYSTEM_TIME(inserted_at, deleted_at), ADD SYSTEM VERSIONING; Limitations: ● Temporal columns don’t have to be INVISIBLE, if they’re often needed ● MDEV-15968: System versioning and CONNECT engine don't work well together: current data is not returned ● MDEV-17448: Support DATETIME(6) for ROW START, ROW END
  • 21. Querying a Sysver Table -- get current version of the rows -- without the temporal columns (they’re INVISIBLE) SELECT * FROM ticket; -- get current version of the rows -- with the temporal columns SELECT *, inserted_at, deleted_at FROM ticket; -- all current and old data SELECT *, inserted_at, deleted_at FROM ticket FOR SYSTEM_TIME ALL;
  • 22. Get old versions of the rows -- get deleted rows SELECT *, inserted_at, deleted_at FROM ticket FOR SYSTEM_TIME FROM '1970-00-00' TO NOW() - 1 MICROSECOND; SELECT *, inserted_at, deleted_at FROM ticket FOR SYSTEM_TIME BETWEEN '1970-00-00' AND NOW() - 1 MICROSECOND; SELECT *, inserted_at, deleted_at FROM ticket FOR SYSTEM_TIME ALL WHERE deleted_at < NOW();
  • 23. History of a row SELECT id, state, inserted_at, deleted_at FROM ticket FOR SYSTEM_TIME ALL WHERE id = 3 ORDER BY deleted_at;
  • 24. Read a row from a specific point in time SELECT id, state FROM ticket FOR SYSTEM_TIME AS OF TIMESTAMP'2020-08-22 08:52:36' WHERE id = 3; SELECT id, state FROM ticket FOR SYSTEM_TIME ALL WHERE id = 3 AND '2020-08-22 08:52:36' BETWEEN inserted_at AND deleted_at;
  • 25. Temporal JOINs -- rows that were present on 07/01 -- whose state did not change after one month SELECT t1.id, t1.inserted_at, t1.deleted_at FROM ticket FOR SYSTEM_TIME ALL AS t1 LEFT JOIN ticket FOR SYSTEM_TIME ALL AS t2 ON t1.id = t2.id AND t1.state = t2.state WHERE '2020-07-01 00:00:00' BETWEEN t1.inserted_at AND t1.deleted_at AND '2020-08-01 00:00:00' BETWEEN t2.inserted_at AND t2.deleted_at AND t2.id IS NULL ORDER BY t1.id;
  • 26. Indexes The ROW END column is automatically appended to: ● The Primary Key; ● All UNIQUE indexes. Queries can use a whole index of its leftmost part, so once a regular table becomes System Versioned queries performance will not degrade. For Application Timed tables, indexes remain unchanged.
  • 27. The power of [bi]Temporal Tables
  • 28. Hints about things you can do ● A table can be both system-versioned and application-timed (bitemporal) ● Stats on added/deleted rows by year, month, weekday, day, daytime… ● Stats on rows lifetime ● Get rows that never changed ● Get rows that change too often, or change at “strange” times ● Examine history of a row to find problems ● ...
  • 29. Hints about things that you should do ● PK should never change, or tracking rows history will be impossible ○ If necessary, use a trigger that throws an error if OLD.id != NEW.id ● Application Time tables: no hard deletions/updates ● If you have to drop a column, move it to a new table to avoid losing the history ● If you have to add a column that is not often read/written, consider putting it into a new table ● If you run stats or complex queries involving temporal columns, add PERSISTENT columns and indexes on them to make queries faster
  • 30. What we left out This was a short introductory session, so we left out some features: ● ALTER TABLEs ○ They may erase or change parts of the history, so they’re disabled by default ● Partitioning ○ You can record the history in a separate partition, or multiple partitions ● Backups ○ Check the docs for problems with Sysver Tables and mysqldump ● Replication / binlog ○ Check the documentation for possible problems with Sysver Tables ○ MariaDB can be a replica of a MySQL server, and make use of Temporal Tables to let analysts run certain analyses that they couldn’t run on MySQL