メインコンテンツまでスキップ
に最終更新

Duplicate Key モデル

Duplicate Key モデルは、Doris のデフォルトのテーブルモデルです。重複排除や集約を行わず、元データの各レコードをそのまま保存します。テーブルを作成する際は、DUPLICATE KEY キーワードを使用してデータ保存時のソート列を指定し、よく使うクエリを最適化します。ソートキーには通常、三列以下を選ぶことを推奨します。ソート列の選び方については、ソートキーを参照してください。

適用シナリオ​

Duplicate Key モデルのデータは通常追記のみで、古いデータは更新されません。元データをすべて保存する必要がある、次のような用途に適しています。

  • ログの保存:アクセスログやエラーログなど、プログラムの動作ログを保存します。後で監査や分析ができるよう、各レコードの詳細を保持する必要があります。
  • ユーザー行動データ:クリックデータやユーザーのアクセス履歴などを分析する場合、後でユーザープロファイルを作成したり、行動経路を詳細に分析したりできるよう、ユーザー行動の詳細を保持する必要があります。
  • 取引データ:取引行動や注文データを保存する場合、通常、取引が完了した後はデータを変更しません。Duplicate Key モデルは、このような取引情報を漏れなく保持できるため、正確な取引照合に適しています。

主な特徴​

Duplicate Key モデルには、次の三つの主な特徴があります。

特徴説明
元データを保持元データをすべて保持し、生データの保存とクエリに適しています。詳細なデータ分析が必要な用途では、Duplicate Key モデルによってデータ損失のリスクを回避できます。
重複排除や集約を行わないAggregate Key モデルや Unique Key モデルとは異なり、Duplicate Key モデルはデータの重複排除や集約を行いません。二行の内容が同じでも、挿入された両方の行がそのまま保持されます。
柔軟なデータクエリ元データをすべて保持するため、完全なデータセットから詳細を取り出し、任意のディメンションで集約できます。これにより、メタデータの監査や詳細な分析が可能になります。

テーブル作成構文​

テーブルを作成する際は、DUPLICATE KEY キーワードで Duplicate Key モデルを指定し、キー列を定義します。Duplicate Key モデルでは、キー列はソートにのみ使用され、一意である必要はありません。

次の例では、ログ情報を保存する Duplicate Key テーブルを作成し、log_time、log_type、error_code の三列でソートします。

CREATE TABLE IF NOT EXISTS example_tbl_duplicate
(
log_time DATETIME NOT NULL,
log_type INT NOT NULL,
error_code INT,
error_msg VARCHAR(1024),
op_id BIGINT,
op_time DATETIME
)
DUPLICATE KEY(log_time, log_type, error_code)
DISTRIBUTED BY HASH(log_type) BUCKETS 10;

データの書き込みと保存​

Duplicate Key テーブルでは、データの重複排除や集約は行われません。挿入されたデータはそのまま保存され、キー列はソートキーとしてのみ使用されます。

列指向ストレージ

上の図に示すように、テーブルには最初に 4 行あります。さらに 2 行を挿入すると、すべてのデータが APPEND モードで保存され、最終的に 6 行が保持されます。

-- Write 4 rows of original data
INSERT INTO example_tbl_duplicate VALUES
('2024-11-01 00:00:00', 2, 2, 'timeout', 12, '2024-11-01 01:00:00'),
('2024-11-02 00:00:00', 1, 2, 'success', 13, '2024-11-02 01:00:00'),
('2024-11-03 00:00:00', 2, 2, 'unknown', 13, '2024-11-03 01:00:00'),
('2024-11-04 00:00:00', 2, 2, 'unknown', 12, '2024-11-04 01:00:00');

-- Append 2 more rows
INSERT INTO example_tbl_duplicate VALUES
('2024-11-01 00:00:00', 2, 2, 'timeout', 12, '2024-11-01 01:00:00'),
('2024-11-01 00:00:00', 2, 2, 'unknown', 13, '2024-11-01 01:00:00');

-- The query result shows that all 6 rows are retained
SELECT * FROM example_tbl_duplicate;
+---------------------+----------+------------+-----------+-------+---------------------+
| log_time | log_type | error_code | error_msg | op_id | op_time |
+---------------------+----------+------------+-----------+-------+---------------------+
| 2024-11-02 00:00:00 | 1 | 2 | success | 13 | 2024-11-02 01:00:00 |
| 2024-11-01 00:00:00 | 2 | 2 | timeout | 12 | 2024-11-01 01:00:00 |
| 2024-11-03 00:00:00 | 2 | 2 | unknown | 13 | 2024-11-03 01:00:00 |
| 2024-11-04 00:00:00 | 2 | 2 | unknown | 12 | 2024-11-04 01:00:00 |
| 2024-11-01 00:00:00 | 2 | 2 | unknown | 13 | 2024-11-01 01:00:00 |
| 2024-11-01 00:00:00 | 2 | 2 | timeout | 12 | 2024-11-01 01:00:00 |
+---------------------+----------+------------+-----------+-------+---------------------+