プライマリキー (PK) は、テーブル内の各行の一意性とデータ整合性を保証します。Hologres のプライマリキーは、従来のデータベースと同様に機能します。プライマリキーは各レコードを一意に識別し、非 NULL である必要があり、複数の列で構成することもできます (複合キー)。このトピックでは、Hologres テーブルのプライマリキーを設定する方法について説明します。
プライマリキーの仕組み
Hologres は、プライマリキーのインデックスファイルを自動的に行指向形式で格納し、高速なキーバリュー (KV) ルックアップを提供します。このインデックスは、プライマリキーを RID (Row Identifier) とクラスタリングキーにマッピングします。RID は自動生成され、アップサートのたびに単調に増加します。このインデックスにより、効率的なプライマリキーの競合検出と、データファイルの高速な特定ができます。テーブルに PK が定義されている場合、システムは PK インデックスを介して RID とクラスタリングキーを特定し、それらを使用してターゲットのデータファイルをピンポイントで特定します。
Hologres でプライマリキーを定義すると、リアルタイムデータウェアハウスのシナリオで重要な機能が有効になります。
-
高性能なアップサートおよび DELETE 操作
従来の追記専用の書き込みに加え、Hologres はプライマリキーを介して、行全体および部分的な列の高性能な更新をサポートします。更新中、システムはテーブル全体をスキャンするのではなく、PK によって対象の行を特定するだけでよいため、データの一意性を維持しながら高スループットのアップサートを実現します。
-
プライマリキーによる高 QPS のポイントクエリ
データ格納形式の設定で説明されているように、テーブルに PK が定義されている場合、PK でフィルタリングするクエリは行全体を迅速に特定できるため、クエリのパフォーマンスが大幅に向上します。これは、PK がデフォルトでクラスタリングキーと分散キーの両方になる行指向テーブルで特に効果的です。これにより、ミリ秒レベルのレイテンシで非常に高い QPS のポイントクエリを実行できるようになり、リアルタイムのリスクコントロール、レコメンデーションエンジン、その他のオンラインサービングシナリオに適しています。
ベストプラクティス
業務上意味のある列をプライマリキーとして選択してください。シリアル型の列をプライマリキーとして使用することは避けてください。書き込み中にテーブルレベルロックを取得するため、書き込みパフォーマンスが低下します。さらに、データが増加するにつれて、シリアル値がオーバーフローする可能性があります。
制限事項
-
プライマリキー列は、一意かつ NOT NULL である必要があります。プライマリキーは、複数の列を含む場合でも、単一のステートメントでのみ定義できます。
-
テーブルレベルの
PRIMARY KEY (col1, col2, ...)制約構文のみがサポートされています。col_name type PRIMARY KEYなどのインライン (列レベル) 構文はサポートされていません。たとえば、id bigint PRIMARY KEYはthe usage of PRIMARY KEY in the create table with ID columns is unsupportedというエラーを返します。代わりにPRIMARY KEY (id)を使用してください。 -
複合プライマリキーは、最大 32 列までサポートします。
-
FLOAT、DOUBLE、NUMERIC、ARRAY、JSON、JSONB、DATE などの複雑なデータ型は、プライマリキー列として使用できません。Hologres V1.3.22 以降、DATE 列がプライマリキーとしてサポートされるようになりました。DATE 列をプライマリキーとして使用するには、インスタンスのバージョンを確認し、必要に応じてアップグレードしてください。詳細については、「インスタンス詳細」および「インスタンスのアップグレード」をご参照ください。
-
行指向テーブルと行列ハイブリッドテーブルにはプライマリキーが必要です。列指向テーブルにはプライマリキーは必要ありません。
-
プライマリキーはテーブル作成後に変更することはできません。プライマリキーを変更するには、テーブルを再作成する必要があります。
例
次の例では、Hologres V2.1 以降で利用可能な構文を使用しています。インスタンスが V2.0 以前の場合は、WITH (property = 'value') 句を CALL set_table_property ステートメントに置き換えてください。詳細については、「CREATE TABLE」をご参照ください。
-
単一のプライマリキーを持つ列指向テーブルを作成します。
-
V2.1 以降でサポートされる構文:
CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id) ) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'age', event_time_column = 'reg_timestamp', bitmap_columns = 'name,class', dictionary_encoding_columns = 'class:auto' ); -
すべてのバージョンでサポートされる構文:
BEGIN; CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id) ); CALL set_table_property('tbl_1', 'orientation', 'column'); CALL set_table_property('tbl_1', 'distribution_key', 'id'); CALL set_table_property('tbl_1', 'clustering_key', 'age'); CALL set_table_property('tbl_1', 'event_time_column', 'reg_timestamp'); CALL set_table_property('tbl_1', 'bitmap_columns', 'name,class'); CALL set_table_property('tbl_1', 'dictionary_encoding_columns', 'class:auto'); COMMIT;
-
-
複合プライマリキー (2 列) を持つ列指向テーブルを作成します。
-
V2.1 以降でサポートされる構文:
CREATE TABLE tbl_2 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text NOT NULL, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id,age) ) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'age', event_time_column = 'reg_timestamp', bitmap_columns = 'name,class', dictionary_encoding_columns = 'class:auto' ); -
すべてのバージョンでサポートされる構文:
BEGIN; CREATE TABLE tbl_2 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text NOT NULL, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id,age) ); CALL set_table_property('tbl_2', 'orientation', 'column'); CALL set_table_property('tbl_2', 'distribution_key', 'id'); CALL set_table_property('tbl_2', 'clustering_key', 'age'); CALL set_table_property('tbl_2', 'event_time_column', 'reg_timestamp'); CALL set_table_property('tbl_2', 'bitmap_columns', 'name,class'); CALL set_table_property('tbl_2', 'dictionary_encoding_columns', 'class:auto'); COMMIT;
-
-
プライマリキーを持つ行指向テーブルを作成します。
-
V2.1 以降でサポートされる構文:
CREATE TABLE public.tbl_row ( id text NOT NULL, name text NOT NULL, class text, PRIMARY KEY (id) ) WITH ( orientation = 'row', distribution_key = 'id', clustering_key = 'id' ); -
すべてのバージョンでサポートされる構文:
BEGIN; CREATE TABLE public.tbl_row ( id text NOT NULL, name text NOT NULL, class text , PRIMARY KEY (id) ); CALL set_table_property('public.tbl_row', 'orientation', 'row'); CALL set_table_property('public.tbl_row', 'clustering_key', 'id'); CALL set_table_property('public.tbl_row', 'distribution_key', 'id'); COMMIT;
-
-
プライマリキーを持つパーティションテーブルを作成します。
-
V2.1 以降でサポートされる構文:
BEGIN; CREATE TABLE public.tbl_parent( a text , b int, c timestamp, d text, ds text, PRIMARY KEY (ds,b) ) PARTITION BY LIST(ds) WITH ( orientation = 'column'); CREATE TABLE public.tbl_child_1 PARTITION OF public.tbl_parent FOR VALUES IN('20221207'); CREATE TABLE public.tbl_child_2 PARTITION OF public.tbl_parent FOR VALUES IN('20221208'); COMMIT; -
すべてのバージョンでサポートされる構文:
BEGIN; CREATE TABLE public.tbl_parent( a text , b int, c timestamp, d text, ds text, PRIMARY KEY (ds,b) ) PARTITION BY LIST(ds); CALL set_table_property('public.tbl_parent', 'orientation', 'column'); CREATE TABLE public.tbl_child_1 PARTITION OF public.tbl_parent FOR VALUES IN('20221207'); CREATE TABLE public.tbl_child_2 PARTITION OF public.tbl_parent FOR VALUES IN('20221208'); COMMIT;
-
関連トピック
-
クエリパターンに基づいたテーブルプロパティの選択に関するガイドラインについては、「Hologres テーブルプロパティのベストプラクティス」をご参照ください。
-
キーバリュールックアップシナリオにおけるテーブル設計とクエリのベストプラクティスについては、「高速なポイントクエリのベストプラクティス」をご参照ください。
-
Hologres 内部テーブルに関連する DDL ステートメントについては、以下をご参照ください。