sql >> データベース >  >> RDS >> MariaDB

MariaDBテンポラルテーブルとは何ですか?

    10.3.4以降、MariaDBにはテンポラルテーブルが付属しています。それはまだ非常に珍しい機能であり、それらのテーブルが何であるか、そしてそれらが何に役立つかについて少し議論したいと思います。

    まず、誰かがこのブログのタイトルを読み間違えた場合に備えて、ここでは、MariaDBにも存在する一時テーブルではなく一時テーブルについて話します。ただし、共通点はあります。時間。一時テーブルは短命ですが、一時テーブルは時間の経過とともにデータにアクセスできるように設計されています。つまり、一時テーブルは、過去のデータにアクセスして変更し、どのような変更がいつ行われたかを確認するために使用できるバージョン管理されたテーブルとして表示できます。また、特定の時点にデータをロールバックするために使用することもできます。

    MariaDBで時間テーブルを使用する方法

    一時テーブルを作成するには、CREATETABLEコマンドに「WITHSYSTEMVERSIONING」を追加するだけです。通常のテーブルを一時的なテーブルに変換する場合は、次を実行できます。

    ALTER TABLE mytable ADD SYSTEM VERSIONING;
    これでほぼすべてです。一時テーブルが作成され、そのデータのクエリを開始できます。これを行うにはいくつかの方法があります。

    まず、SELECTを使用して、特定の時点のデータをクエリできます。

    SELECT * FROM mytable FOR SYSTEM_TIME AS OF TIMESTAMP ‘2020-06-26 10:00:00’;

    範囲のクエリを実行することもできます:

    SELECT * FROM mytable FOR SYSTEM_TIME FROM ‘2020-06-26 08:00:00’ TO ‘2020-06-26 10:00:00’;
    すべてのデータを表示することもできます:

    SELECT * FROM mytable FOR SYSTEM_TIME ALL;

    必要に応じて、上記と同じパターンに従って、時間テーブルからビューを作成できます。

    データ全体でまったく同じ状態を確認したい場合は、すべてのノードで同じ行が同時に更新されない場合があります(たとえば、レプリケーションによる遅延)。複数のスレーブの場合、InnoDBトランザクションIDを使用して時点を定義できます:

    SELECT * FROM mytable FOR SYSTEM_TIME AS OF TRANSACTION 123;

    デフォルトでは、現在のバージョンと古いバージョンの行の両方で、すべてのデータが同じテーブルに保存されます。これにより、最近のデータのみをクエリするときにオーバーヘッドが追加される可能性があります。パーティションを使用して、履歴データを格納するための1つ以上のパーティションと、行の最近のバージョンを格納するための1つ以上のパーティションを作成することにより、このオーバーヘッドを減らすことができます。次に、パーティションプルーニングを使用して、MariaDBは、クエリの結果を出すためにクエリする必要のあるデータの量を減らすことができます。

    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
    
      );

    パーティションごとに格納する行数を定義するなど、パーティション化の他の手段を使用することもできます。

    パーティショニングを使用する場合、古いパーティションを削除することで、データローテーションなどの通常のパーティショニングのベストプラクティスを適用できるようになりました。パーティションを作成しなかった場合でも、次のようなコマンドを使用して作成できます。

    DELETE HISTORY FROM mytable;
    
    DELETE HISTORY FROM mytable BEFORE SYSTEM_TIME '2020-06-01 00:00:00';

    必要に応じて、バージョン管理から一部の列を除外できます:

    CREATE TABLE mytable (
    
       a INT,
    
       b INT WITHOUT SYSTEM VERSIONING
    
    ) WITH SYSTEM VERSIONING;

    MariaDB 10.4では、アプリケーション期間という新しいオプションが追加されました。つまり、基本的に、システム時間の代わりに、テーブルの2つの列(時間ベース)に基づいてバージョン管理を作成することができます。

    CREATE TABLE mytable (
    
       a INT, 
    
       date1 DATE,
    
       date2 DATE,
    
       PERIOD FOR date_period(date1, date2));

    時間に基づいて行を更新または削除することもできます(UPDATEFORPORTIONおよびDELETEFORPORTION)。アプリケーション時とシステム時のバージョン管理を1つのテーブルに混在させることもできます。

    MariaDBの時間テーブルの例

    わかりました。可能性について説明しました。時間テーブルでできることのいくつかを見てみましょう。

    最初に、テーブルを作成してデータを入力しましょう:

    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)

    では、いくつかの行を更新しましょう:

    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

    では、テーブルに格納されているすべての行を見てみましょう。

    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)

    ご覧のとおり、テーブルには、行の現在のバージョンだけでなく、更新前の元の値も含まれています。

    では、時刻を確認してから、さらに行を追加しましょう。現在のバージョンと過去のバージョンを確認できるかどうかを確認します。

    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;

    では、テーブルの内容を確認しましょう。行の現在のバージョンのみ:

    MariaDB [versioned]> SELECT * FROM mytable;
    
    +------+------+
    
    | a    | b    |
    
    +------+------+
    
    |    1 |    3 |
    
    |    2 |    2 |
    
    |    3 |    1 |
    
    |    4 |    1 |
    
    |    5 |    1 |
    
    +------+------+
    
    5 rows in set (0.000 sec)

    次に、挿入と更新を行う前のテーブルの状態にアクセスしましょう。

    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)
    期待どおりに機能します。テーブルには3行しか表示されません。

    この短い例は、決して広範ではありません。テンポラルテーブルを操作する方法について説明したいと思います。これのアプリケーションはたくさんあります。 eコマースでの注文の状態の追跡、コンテンツ(構成ファイル、ドキュメント)のバージョン管理、分析目的での過去のデータへの洞察の改善。

    明確にするために、この機能は、行を更新せずに挿入し続ける限り、「従来の」テーブルを使用して実装できますが、一時テーブルを使用すると管理がはるかに簡単になります。


    1. JDBCが正しいステートメントでMySQLSyntaxError例外を返す

    2. SQLサーバーで日付データ型を使用するにはどうすればよいですか?

    3. UTC_TIMEの例– MySQL

    4. 外部キーをNULLにしたり、重複させたりすることはできますか?