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

Hologres:生成列 (ベータ版)

最終更新日:Nov 09, 2025

生成列は、他の列から計算される特別な列です。これらは、格納された生成列と仮想生成列に分けられます。 Hologres V3.1 以降では、格納された生成列がサポートされています。これは、データの書き込みまたは更新時に自動的に計算され、ストレージ容量を占有します。仮想生成列はまだサポートされていません。このトピックでは、Hologres で格納された生成列を使用する方法について説明します。

シナリオ

  • 必須フィールドの自動計算:計算ロジックの手動処理が不要になります。

  • データの整合性:人為的なミスやコードロジックの問題による不整合を防ぎます。

  • クエリパフォーマンスの最適化:高頻度クエリシナリオでは、格納された生成列の読み取りは通常の列の読み取りと同じです。

  • ビジネスロジックの簡素化:固定された一般的なデータ変換操作の SQL の複雑さを軽減します。

ビジネスニーズに基づいて生成列を適切に使用することで、開発効率を大幅に向上させ、データの信頼性を確保できます。

構文

GENERATED ALWAYS AS 句を使用して生成列を宣言し、STORED キーワードを使用して格納された生成列を指定します。

  • 生成列を含むテーブルを作成します。

    CREATE TABLE generated_col_t (
        [...,]
        col1 INT,
        col2 INT GENERATED ALWAYS AS (col1 + 1) STORED
    );
  • 生成列を含む論理パーティションテーブルを作成し、生成列をパーティションキーとして使用します。

    CREATE TABLE generated_col_logical_part (
        a TEXT,
        b INT,
        ts TIMESTAMP NOT NULL,
        d TIMESTAMP GENERATED ALWAYS AS (date_trunc('day', ts)) STORED NOT NULL
    )
    LOGICAL PARTITION BY LIST(d);

注意事項

  • CREATE TABLE

    • 生成列を定義する場合、IMMUTABLE 関数または式のみがサポートされます。 CURRENT_DATE や RANDOM などの非 IMMUTABLE 関数はサポートされていません。

    • 生成列を定義する場合、式は他の生成列を参照できません。また、生成列に default キーワードを定義することもできません。

    • パーティションテーブルを作成する場合、論理パーティションテーブル のパーティションキーを生成列として設定できますが、物理パーティションテーブル のパーティションキーを生成列として設定することはできません。パーティションテーブルの通常の列は、生成列として設定できます。

    • CREATE FOREIGN TABLE を使用して外部テーブルを作成する場合、生成列はサポートされません。

    • 生成列は、プライマリキー、分散キー、セグメントキー、クラスタ化インデックス、ビットマップインデックス、辞書エンコード列など、さまざまな Hologres インデックスとして設定できます。

  • ALTER TABLE

    • 列を生成列として追加することはできません。

    • 生成列を削除できます。ただし、生成列を削除する前に、参照されている列を削除することはサポートされていません。

    • 生成列のデータ型、または参照されている列のデータ型を変更することはできません。この目的を達成するには、REBUILD 機能を使用することをお勧めします。詳細については、「REBUILD(ベータ版)」をご参照ください。

    • 生成列の名前を変更できます。

  • DML/DQL

    • 生成列を含むテーブルにデータを書き込んだり更新したりする場合、生成列を省略するか、生成列に default キーワードを使用できます。生成列に値を直接書き込むことはできません。

    • データを更新する場合、生成列またはその参照列が分散キーである場合、その列の更新はサポートされていません。

    • 固定プランを使用してデータを更新する場合、プライマリキーが生成列である場合、生成列の参照列の更新はサポートされていません。

    • 固定プランを使用して部分列の更新を実行する場合、生成列が複数の通常の列を参照している場合、これらの列の一部のみを更新することはサポートされていません。

    • 生成列を持つテーブルに対するその他の操作はすべてサポートされています。これには、HQE エンジンを介して実行される読み取りおよび書き込み操作、固定プランを介して実行される読み取りおよび書き込み操作、およびコピーなどの操作が含まれます。

  • その他の操作

    • CREATE TABLE LIKE を使用する場合、ソーステーブルに生成列を含めることができます。生成列のプロパティを保持するには、hg_experimental_enable_create_table_like_properties パラメーターを有効にする必要があります。

    • CREATE TABLE AS を使用する場合、生成列を持つ元のテーブルはサポートされていません。

    • 生成列を持つテーブルのパラメーターを変更するには、REBUILD 構文を使用できます(テーブルのテーブルグループの移行を含む)。詳細については、「REBUILD(ベータ版)」をご参照ください。 HG_MOVE_TABLE_TO_TABLE_GROUP 構文を使用してテーブルのテーブルグループを移行することはサポートされていません。

    • 生成列を含むテーブルに対して INSERT OVERWRITE 操作を実行するには、ネイティブの INSERT OVERWRITE 構文を使用する必要があります。これは Hologres V3.1 以降でサポートされています。元の hg_insert_overwrite 構文はサポートされていません。詳細については、「INSERT OVERWRITE」をご参照ください。

  1. 生成列を含むテーブルを作成します。

    CREATE TABLE generated_col_t (
        id INT PRIMARY KEY,
        col1 INT,
        col2 INT GENERATED ALWAYS AS (col1 + 1) STORED
    );
  2. データをインポートします。

    • 生成されていないすべての列にデータをインポートできます。例:

      INSERT INTO generated_col_t VALUES (1, 1);
      INSERT INTO generated_col_t(id, col1) VALUES (2, 2);

      クエリ SELECT * FROM generated_col_t; は次の結果を返します。

      id	col1	col2
      1	1	2
      2	2	3
    • データをインポートする際に、生成列に default キーワードを使用できます。例:

      INSERT INTO generated_col_t VALUES (3, 3, default);
      INSERT INTO generated_col_t(id, col1, col2) VALUES (4, 4, default);

      クエリ SELECT * FROM generated_col_t; は次の結果を返します。

      id	col1	col2
      4	4	5
      2	2	3
      3	3	4
      1	1	2
    • サポートされていません:生成列に直接データをインポートします。例:

      INSERT INTO generated_col_t VALUES (5, 5, 6);
      INSERT INTO generated_col_t(id, col1, col2) VALUES (6, 6, 7);

      次の結果が返されます。

      a1 - 副本

  3. データを更新します。

    • 生成されていない列を更新できます。例:

      UPDATE generated_col_t SET col1 = 2 WHERE id = 1;

      クエリ SELECT * FROM generated_col_t; は次の結果を返します。

      id	col1	col2
      2	2	3
      3	3	4
      4	4	5
      1	2	3     -- この行は変更されています
    • データを更新する際に、生成列に default キーワードを使用できます。例:

      UPDATE generated_col_t SET col1 = 3, col2 = default WHERE id = 2;

      クエリ SELECT * FROM generated_col_t; は次の結果を返します。

      id	col1	col2
      3	3	4
      2	3	4    -- この行は変更されています
      4	4	5
      1	2	3
    • サポートされていません:生成列を直接更新します。例:

      UPDATE generated_col_t SET col2 = 4 WHERE id = 3;

      次の結果が返されます。

      777

次の SQL クエリを使用して、特定のパラメーター型に対して関数が IMMUTABLE であるかどうかを確認できます。たとえば、TO_CHAR 関数は、入力が TIMESTAMP WITH TIME ZONE 型の場合にのみ IMMUTABLE です。したがって、この関数を生成列で使用する場合は、パラメーターの型が一致していることを確認する必要があります。

SELECT n.nspname AS "Schema",
  p.proname AS "Name",
  pg_catalog.pg_get_function_result(p.oid) AS "Result data type",
  pg_catalog.pg_get_function_arguments(p.oid) AS "Argument data types",
 CASE p.prokind
  WHEN 'a' THEN 'agg'
  WHEN 'w' THEN 'window'
  WHEN 'p' THEN 'proc'
  ELSE 'func'
 END AS "Type",
 CASE
  WHEN p.provolatile = 'i' THEN 'immutable'
  WHEN p.provolatile = 's' THEN 'stable'
  WHEN p.provolatile = 'v' THEN 'volatile'
 END AS "Volatility",
 CASE
  WHEN p.proparallel = 'r' THEN 'restricted'
  WHEN p.proparallel = 's' THEN 'safe'
  WHEN p.proparallel = 'u' THEN 'unsafe'
 END AS "Parallel",
 pg_catalog.pg_get_userbyid(p.proowner) AS "Owner",
 CASE WHEN prosecdef THEN 'definer' ELSE 'invoker' END AS "Security",
 pg_catalog.array_to_string(p.proacl, E'\n') AS "Access privileges",
 l.lanname AS "Language",
 p.prosrc AS "Source code",
 pg_catalog.obj_description(p.oid, 'pg_proc') AS "Description"
FROM pg_catalog.pg_proc p
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
     LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang
-- 対象の関数
WHERE p.proname OPERATOR(pg_catalog.~) '^(TO_CHAR)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_function_is_visible(p.oid)
ORDER BY 1, 2, 4;