ReplacingMergeTree テーブルエンジン
このエンジンは、MergeTree とは異なり、同じソートキー値(テーブル定義の ORDER BY セクションで指定されるもので、PRIMARY KEY ではありません)を持つ重複エントリを削除します。
データの重複排除はマージ時にのみ行われます。マージはバックグラウンドで不定のタイミングで実行されるため、そのタイミングを前提として計画することはできません。一部のデータは未処理のまま残る可能性があります。OPTIMIZE クエリを使用してオンデマンドでマージを実行することもできますが、OPTIMIZE クエリは大量のデータを読み書きするため、それに依存しないでください。
したがって、ReplacingMergeTree はバックグラウンドで重複データを削除してディスク使用量を削減する用途には適していますが、重複がまったく存在しないことを保証するものではありません。
ベストプラクティスやパフォーマンス最適化の方法を含む ReplacingMergeTree の詳細なガイドはこちらにあります。
テーブルを作成する
リクエストパラメータの詳細については、ステートメントの説明を参照してください。
行の一意性は PRIMARY KEY ではなく、テーブルの ORDER BY 句によって決定されます。
ReplacingMergeTree のパラメーター
ver
ver — バージョン番号を保持するカラム。型は UInt*、Date、DateTime または DateTime64。省略可能なパラメーターです。
マージ時に、ReplacingMergeTree は同じソートキーを持つすべての行のうち 1 行だけを残します:
verが設定されていない場合は、選択集合の中で最後の行。選択集合とは、マージに参加するパーツ集合内の行の集合のことです。もっとも最近作成されたパーツ(最後に挿入されたもの)が選択集合の中で最後になります。したがって、重複排除後は、もっとも新しい挿入からのそれぞれの一意なソートキーについて、いちばん最後の行が残ります。verが指定されている場合は、最大のバージョンを持つ行。複数の行でverが同じ場合、それらには「verが指定されていない場合」のルールが適用されます。つまり、もっとも最近に挿入された行が残ります。
Example:
is_deleted
is_deleted — マージ処理の際に、この行のデータが「状態」を表すのか、あるいは削除対象なのかを判定するために使用されるカラム名です。1 は「削除された」行、0 は「状態」の行を表します。
カラムのデータ型 — UInt8。
is_deleted は ver が使用されている場合にのみ有効化できます。
どのようなデータ操作であっても、バージョン番号は増加させる必要があります。2 つの挿入行が同じバージョン番号を持つ場合、後から挿入された行が保持されます。
デフォルトでは、ClickHouse はキーに対して最後の行を保持し、その行が削除行であっても保持します。これは、将来より低いバージョンの行が挿入された場合でも、安全に挿入でき、その削除行が引き続き適用されるようにするためです。
このような削除行を恒久的に削除するには、テーブル設定 allow_experimental_replacing_merge_with_cleanup を有効にし、次のいずれかを実行します。
-
テーブル設定
enable_replacing_merge_with_cleanup_for_min_age_to_force_merge、min_age_to_force_merge_on_partition_only、min_age_to_force_merge_secondsを設定します。パーティション内のすべてのパーツがmin_age_to_force_merge_secondsより古い場合、ClickHouse はそれらを 1 つのパーツにマージし、すべての削除行を削除します。 -
手動で
OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUPを実行します。
Example:
select * from myThirdReplacingMT final;
0 rows in set. Elapsed: 0.003 sec.
-- is_deleted が設定されている行を削除 OPTIMIZE TABLE myThirdReplacingMT FINAL CLEANUP;
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 00:00:00', 0);
select * from myThirdReplacingMT final;
┌─key─┬─someCol─┬───────────eventTime─┬─is_deleted─┐ │ 1 │ first │ 2020-01-01 00:00:00 │ 0 │ └─────┴─────────┴─────────────────────┴────────────┘
クエリ句
ReplacingMergeTree テーブルを作成する場合は、MergeTree テーブルを作成する場合と同様に、同じ 句 が必要です。
テーブル作成の非推奨な方法
新しいプロジェクトではこの方法を使用しないでください。可能であれば、既存のプロジェクトも上記で説明した方法に切り替えてください。
ver を除くすべてのパラメータは、MergeTree の場合と同じ意味を持ちます。
ver- バージョンを表すカラム。省略可能なパラメータです。詳細については上記の説明を参照してください。
クエリ時の重複排除と FINAL
マージ処理の際に、ReplacingMergeTree は ORDER BY 列(テーブル作成時に使用した列)の値を一意の識別子として用いて重複行を識別し、最も新しいバージョンのみを保持します。ただし、これはあくまで最終的な整合性しか提供せず、行が必ず重複排除されることを保証するものではないため、これに依存すべきではありません。その結果、更新行や削除行がクエリで考慮されることにより、クエリが誤った結果を返す可能性があります。
正しい結果を得るためには、バックグラウンドでのマージ処理に加えて、クエリ時の重複排除および削除済み行の除去を行う必要があります。これは FINAL 演算子を使用することで実現できます。例えば、次の例を考えてみます。
FINAL を指定せずにクエリすると、不正確なカウント結果になります(具体的な値はマージ状況によって変動します)。
FINAL を追加すると、正しい結果が得られます。
FINAL の詳細や FINAL のパフォーマンス最適化方法については、ReplacingMergeTree に関する詳細ガイド を参照することを推奨します。`