Poczynając od 10.3.4, MariaDB zawiera tabele czasowe. Jest to wciąż dość rzadka funkcja i chcielibyśmy trochę omówić, czym są te tabele i do czego mogą się przydać.
Po pierwsze, na wypadek, gdyby ktoś błędnie odczytał tytuł tego bloga, mówimy tutaj o tabelach tymczasowych, a nie o tabelach tymczasowych, które również istnieją w MariaDB. Mają jednak coś wspólnego. Czas. Tabele tymczasowe są krótkotrwałe, z drugiej strony tabele tymczasowe mają na celu zapewnienie dostępu do danych w czasie. Krótko mówiąc, możesz zobaczyć tabele czasowe jako tabelę wersjonowaną, która może być używana do uzyskiwania dostępu i modyfikowania danych z przeszłości, znajdowania, jakie zmiany zostały wprowadzone i kiedy. Może być również używany do cofania danych do określonego punktu w czasie.
Jak używać tabel danych czasowych w MariaDB
Aby utworzyć tabelę czasową, wystarczy dodać „Z WERSJĄ SYSTEMU” do polecenia CREATE TABLE. Jeśli chcesz przekonwertować zwykłą tabelę na tabelę czasową, możesz uruchomić:
ALTER TABLE mytable ADD SYSTEM VERSIONING;
To prawie wszystko. Zostanie utworzona tabela czasowa i możesz zacząć odpytywać jej dane. Można to zrobić na kilka sposobów.
Po pierwsze, możemy użyć SELECT do zapytania o dane z określonego czasu:
SELECT * FROM mytable FOR SYSTEM_TIME AS OF TIMESTAMP ‘2020-06-26 10:00:00’;
Możesz również wykonać zapytanie dla zakresu:
SELECT * FROM mytable FOR SYSTEM_TIME FROM ‘2020-06-26 08:00:00’ TO ‘2020-06-26 10:00:00’;
Możliwe jest również pokazanie wszystkich danych:
SELECT * FROM mytable FOR SYSTEM_TIME ALL;
W razie potrzeby możesz tworzyć widoki z tabel czasowych, według tego samego wzorca, który pokazaliśmy powyżej.
Biorąc pod uwagę, że te same wiersze mogą nie być aktualizowane we wszystkich węzłach jednocześnie (na przykład opóźnienia spowodowane replikacją), jeśli chcesz zobaczyć dokładnie ten sam stan danych w całym wiele urządzeń podrzędnych, możesz zdefiniować punkt czasu za pomocą identyfikatora transakcji InnoDB:
SELECT * FROM mytable FOR SYSTEM_TIME AS OF TRANSACTION 123;
Domyślnie wszystkie dane są przechowywane w tej samej tabeli, zarówno aktualna, jak i stara wersja wierszy. Może to zwiększyć obciążenie w przypadku zapytań tylko o najnowsze dane. Można użyć partycji, aby zmniejszyć ten narzut, tworząc jedną lub więcej partycji do przechowywania danych historycznych i jedną do przechowywania najnowszych wersji wierszy. Następnie, korzystając z przycinania partycji, MariaDB będzie w stanie zmniejszyć ilość danych, które musi wykonać, aby uzyskać wynik zapytania:
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
);
Możesz także użyć innych sposobów partycjonowania, takich jak na przykład określenie liczby wierszy do przechowywania na partycję.
Podczas korzystania z partycjonowania możemy teraz zastosować regularne najlepsze praktyki partycjonowania, takie jak rotacja danych poprzez usunięcie starych partycji. Jeśli nie utworzyłeś partycji, nadal możesz to zrobić za pomocą poleceń takich jak:
DELETE HISTORY FROM mytable;
DELETE HISTORY FROM mytable BEFORE SYSTEM_TIME '2020-06-01 00:00:00';
W razie potrzeby możesz wykluczyć niektóre kolumny z wersjonowania:
CREATE TABLE mytable (
a INT,
b INT WITHOUT SYSTEM VERSIONING
) WITH SYSTEM VERSIONING;
W MariaDB 10.4 dodano nową opcję, okresy aplikacji. Oznacza to w zasadzie, że zamiast czasu systemowego można stworzyć wersjonowanie na podstawie dwóch kolumn (czasowych) w tabeli:
CREATE TABLE mytable (
a INT,
date1 DATE,
date2 DATE,
PERIOD FOR date_period(date1, date2));
Możliwe jest również aktualizowanie lub usuwanie wierszy na podstawie czasu (AKTUALIZACJA DLA PORCJI i USUWANIE DLA PORCJI). Możliwe jest również łączenie wersjonowania czasu aplikacji i czasu systemu w jednej tabeli.
Przykłady tabel danych czasowych w MariaDB
Ok, omówiliśmy możliwości, przyjrzyjmy się niektórym rzeczom, które możemy zrobić z tabelami czasowymi.
Najpierw utwórzmy tabelę i wypełnijmy ją danymi:
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)
Teraz zaktualizujmy kilka wierszy:
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
Teraz zobaczmy wszystkie wiersze przechowywane w tabeli:
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)
Jak widać, tabela zawiera nie tylko aktualne wersje wierszy, ale także oryginalne wartości, sprzed ich aktualizacji.
Teraz sprawdźmy, która jest godzina, a następnie dodajmy więcej wierszy. Zobaczymy, czy możemy zobaczyć aktualną i przeszłą wersję.
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;
Teraz sprawdźmy zawartość tabeli. Tylko aktualne wersje wierszy:
MariaDB [versioned]> SELECT * FROM mytable;
+------+------+
| a | b |
+------+------+
| 1 | 3 |
| 2 | 2 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
+------+------+
5 rows in set (0.000 sec)
Następnie przejdźmy do stanu tabeli przed wykonaniem wstawek i aktualizacji:
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)
Działa zgodnie z oczekiwaniami, widzimy tylko trzy wiersze w tabeli.
Ten krótki przykład w żadnym wypadku nie jest obszerny. Chcieliśmy dać Ci wyobrażenie, jak możesz obsługiwać tabele temporalne. Zastosowania tego są liczne. Lepsze śledzenie stanu zamówienia w e-commerce, wersjonowanie zawartości (pliki konfiguracyjne, dokumenty), wgląd w dane z przeszłości w celach analitycznych.
Aby było jasne, tę funkcję można zaimplementować przy użyciu „tradycyjnych” tabel, o ile wstawiasz wiersze, a nie je aktualizujesz, ale zarządzanie jest znacznie łatwiejsze, gdy używasz tabel tymczasowych.