Ab 10.3.4 enthält MariaDB temporale Tabellen. Es ist immer noch ein ziemlich ungewöhnliches Feature und wir würden gerne ein wenig diskutieren, was diese Tabellen sind und wofür sie nützlich sein können.
Zunächst einmal, falls jemand den Titel dieses Blogs falsch gelesen hat, wir sprechen hier von temporären Tabellen, nicht von temporären Tabellen, die ebenfalls in MariaDB vorhanden sind. Sie haben jedoch etwas gemeinsam. Zeit. Temporäre Tabellen sind kurzlebig, temporale Tabellen hingegen sollen den Zugriff auf die Daten im Laufe der Zeit ermöglichen. Kurz gesagt, Sie können temporale Tabellen als versionierte Tabelle sehen, die verwendet werden kann, um auf frühere Daten zuzugreifen und diese zu ändern, um herauszufinden, welche Änderungen wann vorgenommen wurden. Es kann auch verwendet werden, um Daten auf einen bestimmten Zeitpunkt zurückzusetzen.
Wie man temporäre Tabellen in MariaDB verwendet
Um eine temporale Tabelle zu erstellen, müssen wir nur „WITH SYSTEM VERSIONING“ zum CREATE TABLE-Befehl hinzufügen. Wenn Sie eine reguläre Tabelle in eine temporale umwandeln möchten, können Sie Folgendes ausführen:
ALTER TABLE mytable ADD SYSTEM VERSIONING;
Das ist so ziemlich alles. Eine temporale Tabelle wird erstellt und Sie können mit der Abfrage ihrer Daten beginnen. Dafür gibt es mehrere Möglichkeiten.
Zunächst können wir mit SELECT Daten zu einem bestimmten Zeitpunkt abfragen:
SELECT * FROM mytable FOR SYSTEM_TIME AS OF TIMESTAMP ‘2020-06-26 10:00:00’;
Sie können auch eine Bereichsabfrage durchführen:
SELECT * FROM mytable FOR SYSTEM_TIME FROM ‘2020-06-26 08:00:00’ TO ‘2020-06-26 10:00:00’;
Es ist auch möglich alle Daten anzuzeigen:
SELECT * FROM mytable FOR SYSTEM_TIME ALL;
Bei Bedarf können Sie Ansichten aus temporalen Tabellen erstellen, indem Sie dem gleichen Muster folgen, das wir oben gezeigt haben.
Angesichts der Tatsache, dass dieselben Zeilen möglicherweise nicht auf allen Knoten gleichzeitig aktualisiert werden (z. B. durch Replikation verursachte Verzögerungen), wenn Sie genau denselben Zustand der Daten über die mehrere Slaves, können Sie den Zeitpunkt über die InnoDB-Transaktions-ID:
definierenSELECT * FROM mytable FOR SYSTEM_TIME AS OF TRANSACTION 123;
Standardmäßig werden alle Daten in derselben Tabelle gespeichert, sowohl aktuelle als auch alte Versionen der Zeilen. Dies kann zusätzlichen Overhead verursachen, wenn Sie nur die letzten Daten abfragen. Es ist möglich, Partitionen zu verwenden, um diesen Overhead zu reduzieren, indem eine oder mehrere Partitionen zum Speichern historischer Daten und eine zum Speichern der letzten Versionen der Zeilen erstellt werden. Dann kann MariaDB mithilfe von Partition Pruning die Datenmenge reduzieren, die abgefragt werden muss, um das Ergebnis für die Abfrage zu erhalten:
CREATE TABLE mytable (a INT) WITH SYSTEM VERSIONING
PARTITION BY SYSTEM_TIME INTERVAL 1 WEEK (
PARTITION p0 HISTORY,
PARTITION p1 HISTORY,
PARTITION p2 HISTORY,
PARTITION pcur CURRENT
);
Sie können auch andere Mittel zur Partitionierung verwenden, wie beispielsweise die Definition der Anzahl der pro Partition zu speichernden Zeilen.
Bei der Verwendung der Partitionierung können wir jetzt bewährte Vorgehensweisen für die normale Partitionierung anwenden, z. B. Datenrotation, indem alte Partitionen entfernt werden. Wenn Sie keine Partitionen erstellt haben, können Sie dies dennoch mit Befehlen wie:
tunDELETE HISTORY FROM mytable;
DELETE HISTORY FROM mytable BEFORE SYSTEM_TIME '2020-06-01 00:00:00';
Bei Bedarf können Sie einige Spalten von der Versionierung ausschließen:
CREATE TABLE mytable (
a INT,
b INT WITHOUT SYSTEM VERSIONING
) WITH SYSTEM VERSIONING;
In MariaDB 10.4 wurde eine neue Option hinzugefügt, Bewerbungszeiträume. Das bedeutet im Grunde, dass anstelle der Systemzeit eine Versionierung basierend auf zwei Spalten (zeitbasiert) in der Tabelle erstellt werden kann:
CREATE TABLE mytable (
a INT,
date1 DATE,
date2 DATE,
PERIOD FOR date_period(date1, date2));
Es ist auch möglich, Zeilen basierend auf der Zeit zu aktualisieren oder zu löschen (UPDATE FOR PORTION und DELETE FOR PORTION). Es ist auch möglich, Anwendungszeit- und Systemzeit-Versionierung in einer Tabelle zu mischen.
Beispiele für temporäre Tabellen in MariaDB
Ok, wir haben die Möglichkeiten besprochen, werfen wir einen Blick auf einige Dinge, die wir mit temporalen Tabellen machen können.
Erstellen wir zunächst eine Tabelle und füllen sie mit einigen Daten:
MariaDB [(none)]> CREATE DATABASE versioned;
Query OK, 1 row affected (0.000 sec)
MariaDB [(none)]> use versioned
Database changed
MariaDB [versioned]> CREATE TABLE mytable (a INT, b INT) WITH SYSTEM VERSIONING;
Query OK, 0 rows affected (0.005 sec)
MariaDB [versioned]> INSERT INTO mytable VALUES (1,1);
Query OK, 1 row affected (0.001 sec)
MariaDB [versioned]> INSERT INTO mytable VALUES (2,1);
Query OK, 1 row affected (0.001 sec)
MariaDB [versioned]> INSERT INTO mytable VALUES (3,1);
Query OK, 1 row affected (0.000 sec)
Jetzt aktualisieren wir einige Zeilen:
MariaDB [versioned]> UPDATE mytable SET b = 2 WHERE a < 3;
Query OK, 2 rows affected (0.001 sec)
Rows matched: 2 Changed: 2 Inserted: 2 Warnings: 0
Sehen wir uns nun alle Zeilen an, die in der Tabelle gespeichert sind:
MariaDB [versioned]> SELECT * FROM mytable FOR SYSTEM_TIME ALL ;
+------+------+
| a | b |
+------+------+
| 1 | 2 |
| 2 | 2 |
| 3 | 1 |
| 1 | 1 |
| 2 | 1 |
+------+------+
5 rows in set (0.000 sec)
Wie Sie sehen können, enthält die Tabelle nicht nur aktuelle Versionen der Zeilen, sondern auch Originalwerte, bevor wir sie aktualisiert haben.
Lassen Sie uns jetzt überprüfen, wie spät es ist, und dann einige weitere Zeilen hinzufügen. Wir werden sehen, ob wir die aktuelle und die frühere Version sehen können.
MariaDB [versioned]> SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2020-06-26 11:24:55 |
+---------------------+
1 row in set (0.000 sec)
MariaDB [versioned]> INSERT INTO mytable VALUES (4,1);
Query OK, 1 row affected (0.001 sec)
MariaDB [versioned]> INSERT INTO mytable VALUES (5,1);
Query OK, 1 row affected (0.000 sec)
MariaDB [versioned]> UPDATE mytable SET b = 3 WHERE a < 2;
Query OK, 1 row affected (0.001 sec)
Rows matched: 1 Changed: 1 Inserted: 1 Warnings: 0;
Lassen Sie uns nun den Inhalt der Tabelle überprüfen. Nur aktuelle Versionen der Zeilen:
MariaDB [versioned]> SELECT * FROM mytable;
+------+------+
| a | b |
+------+------+
| 1 | 3 |
| 2 | 2 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
+------+------+
5 rows in set (0.000 sec)
Lassen Sie uns dann auf den Zustand der Tabelle zugreifen, bevor wir die Einfügungen und Aktualisierungen vorgenommen haben:
MariaDB [versioned]> SELECT * FROM mytable FOR SYSTEM_TIME AS OF TIMESTAMP '2020-06-26 11:24:55';
+------+------+
| a | b |
+------+------+
| 2 | 2 |
| 3 | 1 |
| 1 | 2 |
+------+------+
3 rows in set (0.000 sec)
Funktioniert wie erwartet, wir sehen nur drei Zeilen in der Tabelle.
Dieses kurze Beispiel ist keineswegs umfangreich. Wir wollten Ihnen eine Vorstellung davon geben, wie Sie die temporalen Tabellen bedienen können. Anwendungen davon sind zahlreich. Besseres Tracking des Auftragsstatus im E-Commerce, Versionierung der Inhalte (Konfigurationsdateien, Dokumente), Einblick in die Vergangenheitsdaten für Analysezwecke.
Um es deutlich zu machen, diese Funktion kann mit „herkömmlichen“ Tabellen implementiert werden, solange Sie weiterhin Zeilen einfügen und sie nicht aktualisieren, aber die Verwaltung ist viel einfacher, wenn temporale Tabellen verwendet werden.