Primary Key table
プライマリキーテーブル
テーブルを作成する際に、プライマリキーとソートキーを別々に定義することができます。プライマリキーテーブルにデータがロードされると、StarRocksはデータを保存する前にソートキーに従ってデータをソートします。クエリでは、同じプライマリキーを持つレコードの中で最新のレコードを返します。ユニークキーテーブルとは異なり、プライマリキーテーブルではクエリ中の集計操作を必要とせ ず、プレディケートとインデックスのプッシュダウンもサポートしています。そのため、プライマリキーテーブルはリアルタイムで頻繁にデータが更新される場合でも高速なクエリパフォーマンスを実現することができます。
注意
v3.0より前のバージョンでは、プライマリキーテーブルはプライマリキーとソートキーを切り離すことができません。 v3.1以降、StarRocksの共有データモードではプライマリキーテーブルをサポートしていますが、プライマリキーテーブルの永続インデックスはサポートされていません。
シナリオ
- プライマリキーテーブルは、リアルタイムでデータを頻繁に更新する必要がある以下のシナリオに適しています:
- トランザクション処理システムからデータをリアルタイムでStarRocksにストリームデータとして取り込む。通常、トランザクション処理システムでは、挿入操作に加えて大量の更新と削除操作が行われます。トランザクション処理システムからデータをStarRocksに同期する必要がある場合は、プライマリキーテーブルを使用するテーブルを作成することをお勧めします。その後、Apache Flink®のCDCコネクタなどのツールを使用して、トランザクション処理システムのバイナリログをStarRocksに同期することができます。StarRocksはバイナリログを使用して、テーブルのデータをリアルタイムで追加、削除、および更新します。これにより、データ同期が簡素化され、ユニークキーテーブルのマージオン リード(MoR)テーブルを使用した場合のクエリパフォーマンスが3倍から10倍向上します。例えば、データをロードするために flink-connector-starrocks を使用することができます。詳細については、flink-connector-starrocksを使用してデータをロードするを参照してください。
- 個々のカラムに対して更新操作を実行することで、複数のストリームを結合する。ユーザープロファイリングなどのビジネスシナリオでは、データアナリストが使用する分析モデルの簡素化と多次元解析パフォーマンスの向上のために、フラットテーブルが好まれます。これらのシナリオでの上流データは、ショッピングアプリ、配送アプリ、銀行アプリなどのさまざまなアプリケーション、またはユーザーの異なるタグとプロパティを取得するための計算を行う機械学習システムなどから提供される場合があります。プライマリキーテーブルは、個々のカラムの更新をサポートするため、各アプリケーションまたはシステムは自身のサービス範囲内のデータを保持し、リアルタイムのデータ追加、削除、および更新の恩恵を高速なクエリパフォーマンスで享受することができます。
- プライマリキーテーブルは、プライマリキーによって占有されるメモリが制御可能なシナリオに適しています。StarRocksのストレージエンジンは、プライマリキーテーブルを使用する各テーブルのプライマリキーに対してインデックスを作成します。また、テーブルにデータをロードするときに、StarRocksはプライマリキーのインデックスをメモリにロードします。そのため、プライマリキーテーブ ルは他の3つのテーブルタイプよりも大きなメモリ容量を必要とします。**StarRocksは、プライマリキーを構成するフィールドの総長をエンコード後の127バイトに制限します。**テーブルが以下の特徴を持つ場合は、プライマリキーテーブルを使用することを検討してください。
-
テーブルには、急速に変化するデータと遅く変化するデータの両方が含まれています。急速に変化するデータは最新日数にわたって頻繁に更新され、一方で遅く変化するデータは稀に更新されます。たとえば、解析とクエリのためにMySQLのオーダーテーブルをリアルタイムにStarRocksに同期する必要があるとします。この例では、テーブルのデータは日ごとにパーティションされており、ほとんどの更新は最新の日に作成された注文に対して行われます。履歴的な注文は完了後に更新されなくなります。データロードジョブを実行すると、プライマリキーインデックスはメモリにロードされず、最近更新された注文のインデックスエントリのみがメモリにロードされます。次の図に示すように、テーブルのデータは日ごとにパーティションされ、最も最近の2つのパーティションのデータが頻繁に更新されます。
-
テーブルは、数百または数千のカラムから構成されるフラットテーブルです。プライマリキーはテーブルのデータの一部分のみで構成され、メモリのほんの一部しか使用しません。たとえば、ユーザーステータスやプロファイルテーブルは、数千万から億単位のユーザーから成る大量のカラムから構成されていますが、プライマリキーが占有するメモリ量は制御可能です。次の図に示すように、テーブルにはわずかな行しか含まれておらず、テーブルのプライマリキーはテーブルの一部分のみです。
-
原理
プライマリキーテーブルは、StarRocksが提供する新しいストレージエンジンに基づいて設計されています。プライマリキーテーブルのメタデータ構造と読み書きメカニズムは、ユニークキーテーブルとは異なります。そのため、プライマリキーテーブルは集計操作を必要とせず、プレディケートとインデックスのプッシュダウンをサポートし ています。これにより、クエリパフォーマンスが大幅に向上します。
ユニークキーテーブルでは、モージョンリード(MoR)ポリシーが採用されています。MoRはデータの書き込みを合理化しますが、複数のデータバージョンのオンライン集計が必要です。また、マージオペレータはプレディケートとインデックスのプッシュダウンをサポートしていません。その結果、クエリパフォーマンスが低下します。
プライマリキーテーブルでは、各レコードが一意のプライマリキーを持つようにするために、デリート+インサートポリシ ーが採用されています。つまり、StarRocksは、レコードに対する更新操作を受け取ると、プライマリキーインデックスを検索してレコードを削除し、新しいレコードを挿入します。別の言い方をすれば、StarRocksは更新操作を削除操作と挿入操作の組み合わせとして変換します。
StarRocksはレコードに対する削除操作を受け取ると、プライマリキーインデックスを検索してレコードを削除します。
テーブルの作成
例1: 注文を日次で分析する必要があるとします。この例では、orders
という名前のテーブルを作成し、dt
とorder_id
をプライマリキーとし、他のカラムをメトリックカラムとして定義します。
create table orders (
dt date NOT NULL,
order_id bigint NOT NULL,
user_id int NOT NULL,
merchant_id int NOT NULL,
good_id int NOT NULL,
good_name string NOT NULL,
price int NOT NULL,
cnt int NOT NULL,
revenue int NOT NULL,
state tinyint NOT NULL
) PRIMARY KEY (dt, order_id)
PARTITION BY RANGE(`dt`) (
PARTITION p20210820 VALUES [('2021-08-20'), ('2021-08-21')),
PARTITION p20210821 VALUES [('2021-08-21'), ('2021-08-22')),
...
PARTITION p20210929 VALUES [('2021-09-29'), ('2021-09-30')),
PARTITION p20210930 VALUES [('2021-09-30'), ('2021-10-01'))
) DISTRIBUTED BY HASH(order_id)
PROPERTIES("replication_num" = "3",
"enable_persistent_index" = "true");
NOTICE
例2: ユーザーの住所や最終アクティブ時刻などの次元から、リアルタイムでユーザーの行動を分析する必要があるとします。この場合、テーブルを作成する際に、user_id
カラムをプライマリキーとし、address
カラムとlast_active
カラムの組み合わせをソートキー として定義することができます。
create table users (
user_id bigint NOT NULL,
name string NOT NULL,
email string NULL,
address string NULL,
age tinyint NULL,
sex tinyint NULL,
last_active datetime,
property0 tinyint NOT NULL,
property1 tinyint NOT NULL,
property2 tinyint NOT NULL,
property3 tinyint NOT NULL,
....
) PRIMARY KEY (user_id)
DISTRIBUTED BY HASH(user_id)
ORDER BY(`address`,`last_active`)
PROPERTIES("replication_num" = "3",
"enable_persistent_index" = "true");
使用上の注意点
-
テーブルのプライマリキーについては、次の点に注意してください:
- プライマリキーは、
PRIMARY KEY
キーワードを使用して定義されます。 - プライマリキーは、ユニーク制約が強制されるカラムに作成する必要があり、プライマリキーカラムの名前を変更することはできません。
- プライマリキーカラムは、BOOLEAN、TINYINT、SMALLINT、INT、BIGINT、LARGEINT、STRING、VARCHAR、DATE、DATETIMEのいずれかのデータ型にすることができます。ただし、プライマリキーカラムを
NULL
として定義することはできません。 - パーティションカラムとバケットカラムは、プライマリキーに参加する必要があります。
- プライマリキーカラムの数と総長は、メモリを節約するために適切に設計する必要があります。プライマリキーには、INTおよびBIGINTなどのデータ型のメモリを占有しないカラムを選定することをお勧めします。VARCHARデータ型のカラムをプライマリキーに参加させないようにしてください。
- テーブルの作成前に、プライマリキーカラムのデータ型とテーブルの行数に基づいて、プライマリキーインデックスが占有するメモリを見積もることをお勧めします。これにより、テーブルがメモリを使い果たすことを防ぐことができます。以下の例では、プライマリキーインデックスが占有するメモリの計算方法を説明します:
- DATEデータ型(4バイトを占有)の
dt
カラムとBIGINTデータ型(8バイトを占有)のid
カラムがプライマリキーとして定義されているとします。この場合、プライマリキーの長さは12バイトです。 - テーブルには、10,000,000行のホットデータが含まれていて、3つのレプリカに保存されています。
- 上記の情報に基づいて、プライマリキーインデックスが占有するメモリは次の式に従って945MBです:(12 + 9) x 10,000,000 x 3 x 1.5 = 945 (MB)上記の式では、
9
は行ごとの不変のオーバーヘッドであり、1.5
はハッシュテーブルごとの平均的な追加のオーバーヘッドです。
- DATEデータ型(4バイトを占有)の
- プライマリキーは、
-
enable_persistent_index
: プライマリキーインデックスをディスク上に永続化し、メモリに保存することで、メモリを過剰に使用しないようにすることができます。一般的には、プライマリキーインデックスは以前と比べてメモリの1/10しか使用しません。テーブルを作成する際にPROPERTIES
内でこのプロパティを設定することができます。有効な値は true または false です。デフォルト値は false です。- テーブルを作成した後でこのパラメータを変更する場合は、ALTER TABLEの「テーブルのプロパティを変更する」セクションを参照してください。
- SSDのディスクを使用する場合は、このプロパティを true に設定することをお勧めします。
- StarRocksの共有データモードでは、プライマリキーテーブルの永続インデックスはサポートされていません。
-
ORDER BY
キーワードを使用して、任意のカラムの組み合わせとしてソートキーを指定することができます。注意
ソートキーが指定されている場合、プレフィックスインデックスはソートキーに基づいて構築されます。ソートキーが指定されていない場合、プレフィックスインデックスはプライマリキーに基づいて構築されます。
-
ALTER TABLE
を使用してテーブルスキーマを変更することができますが、以下の制限があります:- プライマリキーの変更はサポートされていません。
ALTER TABLE ... ORDER BY ...
を使用してソートキーを再割り当てることはサポートされていますが、ソートキーの削除はサポートされていません。また、ソートキーのカラムのデータ型を変更することもサポートされていません。- カラムの順序の調整はサポートされていません。
-
v2.3.0以降、プライマリキーカラム以外のカラムは、BITMAPおよびHLLのデータ型をサポートしています。
-
プライマリキーカラム以外のカラムには、BITMAPインデックスまたはBloomフィルタインデックスを作成することができます。
-
v2.4.0以降、プライマリキーテーブルに基づいて非同期マテリアライズドビューを作成することができます。
次の手順
テーブルの作成後、ロードジョブを実行してデータをプライマリキーテーブルにロードできます。サポートされるロード方法の詳細については、データロードの概要を参照してください。
プライマリキーテーブルのデータを更新する必要がある場合は、ロードジョブを実行するかDMLステートメント(UPDATEまたはDELETE)を実行することができます。また、これらの更新操作は原子性を保証します。