すべてのプロダクト
Search
ドキュメントセンター

Hologres:プライマリキー

最終更新日:Jul 14, 2026

プライマリキー (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 KEYthe 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;

関連トピック