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

Hologres:プライマリキー

最終更新日:Mar 11, 2026

テーブルにプライマリキー (PK) を設定することで、各レコードの重複なし(一意性)を保証し、データ整合性を維持するとともに、データ管理を簡素化できます。Hologres におけるプライマリキーは、従来型データベースと同様の属性を持ちます。これは、テーブル内のレコードを一意に識別するための識別子です。プライマリキーとして設定されたフィールドは、すべて一意であり、NULL 値を許容しません。また、複数のフィールドを組み合わせた複合プライマリキーとしても設定可能です。本トピックでは、Hologres におけるテーブルへのプライマリキー設定方法について説明します。

概要

Hologres では、システムが基盤となるストレージレイヤー内でプライマリキーインデックスファイルを自動的に管理します。このファイルはローストア構造を採用しており、高速なキーバリュー (KV) サービスを提供します。インデックスファイル内のキーはテーブルのプライマリキー (PK) であり、値には Row Identifier (RID)(旧称:`unique_id`)およびクラスタリングキーが含まれます。RID は自動生成され、UPSERT 操作ごとに単調増加します。プライマリキーインデックスファイルにより、効率的なプライマリキー競合検出が可能となり、データファイルの位置特定を支援します。テーブルに PK が設定されている場合、プライマリキーインデックスファイルから迅速に RID およびクラスタリングキーを特定できます。その後、これらの情報を用いて対応するデータファイルを特定できます。

Hologres におけるプライマリキーの設定は、リアルタイムデータウェアハウスのさまざまなユースケースに対応するうえで有効です:

  • 高性能な UPSERT および DELETE 操作をサポートします。

    従来型データベースの高パフォーマンスな追記専用書き込み機能に加え、Hologres ではプライマリキーを活用して、全行または特定カラムに対する高性能な更新処理を実現します。書き込み更新を行う際、システムは全表スキャンを実行せず、プライマリキーに基づいてレコードを更新します。これにより、高性能な UPSERT 操作が実現され、データの一意性も保証されます。

  • プライマリキーに基づく高 QPS クエリをサポートします。

    テーブルのストレージフォーマット:列指向、行指向、およびハイブリッド行列表」で説明したとおり、プライマリキーが設定されたテーブルでは、プライマリキーに基づいて全行を迅速に特定できます。これにより、クエリパフォーマンスが向上し、特にプライマリキーがデフォルトでクラスタリングキーおよびディストリビューションキーとなる行指向テーブルにおいて顕著な効果を発揮します。プライマリキーを用いてデータファイルを特定することで、超高速なポイントクエリ(秒間クエリ数 (QPS) が極めて高く、レイテンシがミリ秒単位)を実現でき、リアルタイムリスク管理やリアルタイムレコメンデーションなどのオンラインアプリケーションのユースケースに適しています。

使用上の推奨事項

プライマリキーを設定する際は、業務的な意味を持つフィールドを選択してください。`SERIAL` 型のフィールドをプライマリキーとして使用しないでください。これは、`SERIAL` 型は書き込み時にテーブルロックを使用するため、パフォーマンスが低下するためです。さらに、データ量の増加に伴い、`SERIAL` 型は容易にオーバーフローする可能性があります。

制限事項

  • プライマリキーは、一意かつ NULL を許容しないカラム、またはその組み合わせである必要があります。複合プライマリキーは、単一の文で設定する必要があります。

  • 複合プライマリキーは最大 32 カラムまで指定できます。

  • `FLOAT`、`DOUBLE`、`NUMERIC`、`ARRAY`、`JSON`、`JSONB`、`DATE` などの複雑なデータの型のフィールドをプライマリキーとして設定することはできません。ただし、Hologres V1.3.22 以降では `DATE` 型のフィールドをプライマリキーとして使用することが可能です。`DATE` 型のフィールドをプライマリキーとして使用する場合は、ご利用の Hologres インスタンスのバージョンを確認し、必要に応じてインスタンスをスペックアップしてください。詳細については、「インスタンスの詳細」および「インスタンスのスペックアップ」をご参照ください。

  • 行指向テーブルおよびハイブリッド行列表は、必ずプライマリキーを設定する必要があります。一方、列指向テーブルはプライマリキーの設定が必須ではありません。

  • プライマリキーは変更できません。プライマリキーを変更するには、テーブルを再作成する必要があります。

使用例

以下の例は、Hologres V2.1 以降の構文を示しています。ご利用のインスタンスが V2.0 以前のバージョンの場合、データ定義言語 (DDL) 内の `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,
       class text,
       reg_timestamp timesatmptz, 
      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_1 (
          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;

参考文献