17.00 - 17.05 - 識別列 - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLデータ定義言語 詳細トピック

Product
Advanced SQL Engine
Teradata Database
Release Number
17.00
17.05
Release Date
2020年6月
Content Type
プログラミング リファレンス
Publication ID
B035-1184-170K-JPN
Language
日本語 (日本)

識別列は、主に、システム生成の固有値を取得することで行の固有性を確保するために使用されます。複合インデックスまたはキーが必要でない場合、識別列は、簡単な固有インデックス、プライマリ キー、および代理キーを生成することができます。

また、識別列はいくつかのテーブルをマージするときに確実に列を固有にするために、またはテーブルをロードおよびアンロードするときに重要な事前処理を回避するために、役立ちます。

Teradata Unityで使用するテーブルについては、識別列を作成しないでください。Teradata Unityは確定的に固有の値を生成する独自のメカニズムを備えているため、識別列で複数のTeradata Databaseインスタンスを管理する場合の問題が発生しません。Teradata Unityのドキュメントを参照してください。

行に識別列を割り当てるとその行は固有になるので、既存の行が重複するクライアント システムから識別列を持つテーブルへの行のロードが許可されています。これにより問題が生じる場合には、識別列テーブルにその行をロードする前に重複するデータをフィルタに掛ける必要があります。識別列テーブルの重複値および重複行の問題については、識別列、列値の重複、行の重複を参照してください。

識別列用の様々なパラメータは、DBC.IdColシステム テーブルで保守されています。

識別列には、以下の特性があります。
  • 異なるSTART WITH値が指定されない限り、値1で始まります。
  • 異なるINCREMENT BY値が指定されない限り、1ずつ増えます。

    負のINCREMENT BY値を指定した場合、値を減らすことができます。

  • 一連の値を増やす場合は最大値を、減らす場合は最小値を指定することができます。
  • 値を再利用することができます。
識別列には、以下のルールと制約事項があります。
  • Teradata Unityが管理するテーブルには使用できません。
  • 以下のバルク挿入操作だけをサポートします。
    • 複数の並行セッションを介して明示された単一文INSERT。

      例えば、同じテーブルへの並列BTEQインポート。

    • 複数の並行セッションを介して明示された複文INSERT。

      例えば、Teradata Parallel Data PumpのINSERT。

    • INSERT ... SELECT文。
  • トリガーされたイベントが識別列を持つテーブルへのINSERTである場合、トリガーされたアクション文ブロックまたはトリガーのWHEN句では識別列を参照できません。
  • GENERATED ALWAYS列を更新できません。
  • NO CYCLEも指定するGENERATED ALWAYS列値は、常に固有です。
  • GENERATED BY DEFAULT列は、以下のいずれかの方法でINSERT文によってnullに設定されるときにのみ値を生成します。
    • 複数値内でのNULLの明示指定。

      このLDAP構成の1つ以上のURL。URLには、適切なプロトコル(INSERT INTO table VALUES (1,NULL);または)やポート(など)を含める必要があります。すべてのURLが、同様に構成されたLDAPサーバーを参照する場合にのみ、複数のURLを入力します。プライマリ サーバーにアクセスできないときに使用できるように、DLAPサーバーまたはフェイルオーバーLDAPサーバーを複製する場合がそのようなケースに該当します。

    • 列名リストが提供されていないとき、複数値内の値の省略によるNULLの暗黙指定。

      このLDAP構成の1つ以上のURL。URLには、適切なプロトコル(INSERT INTO table VALUES (1,);または)やポート(など)を含める必要があります。すべてのURLが、同様に構成されたLDAPサーバーを参照する場合にのみ、複数のURLを入力します。プライマリ サーバーにアクセスできないときに使用できるように、DLAPサーバーまたはフェイルオーバーLDAPサーバーを複製する場合がそのようなケースに該当します。

    • コマンド名リストからの列名の省略。

      このLDAP構成の1つ以上のURL。URLには、適切なプロトコル(INSERT INTO table (x) VALUES (1);または)やポート(など)を含める必要があります。すべてのURLが、同様に構成されたLDAPサーバーを参照する場合にのみ、複数のURLを入力します。プライマリ サーバーにアクセスできないときに使用できるように、DLAPサーバーまたはフェイルオーバーLDAPサーバーを複製する場合がそのようなケースに該当します。

      テーブルには、複数の列があります。

  • GENERATED BY DEFAULT列を更新することができます。
  • GENERATED BY DEFAULT列値の固有性は保証されていません。

    GENERATED BY DEFAULT列値の固有性を保証するには、以下の制限のすべてに適合する必要があります。

    • NO CYCLEを指定しなければなりません。
    • 指定するすべてのユーザー指定値は、システム生成値の範囲外でなければなりません。
    • ユーザー指定値の固有性をユーザー自身が定義しなければなりません。
  • 識別列のデータ型を、UDT、Geospatial、ARRAY、VARRAY、またはPERIODにすることはできません。
  • GENERATED ALWAYSの識別列をnullにすることはできません。
  • 固有の識別列値を持つテーブルのカーディナリティは、識別列のデータ型の最大値に制限されます。

    このため、識別列には、固有値の可能な最大数を確実に生成できる数値タイプを指定するようにしてください。

    数値データ型の最大の範囲は、DECIMAL(18,0)、NUMERIC(18,0)、および正確な数のNUMBER(18,0)です。これは約1*1018行になります。概数のNUMBER列を識別列に使用することはできません。

    これは、DBS制御パラメータMaxDecimalが38に設定されている場合でも同じです。詳細については、<Teradata Vantage™ - データ タイプおよびリテラル、B035-1143>および<Teradata Vantage™ - データベース ユーティリティ、B035-1102>を参照してください。識別列に18桁を超える精度を設定したり、large fixed NUMBER型またはBIGINT型を定義したりすることが可能です。その場合、CREATE TABLEまたはALTER TABLE文が警告メッセージを返されません。しかし、識別列機能で生成される値は、DECIMAL(18,0)のデータ型とサイズに限定されたままです。

  • Teradata Parallel Data Pumpを使用してGENERATED BY DEFAULT識別列に挿入する操作では、Teradata Parallel Data Pumpフィールド変数を同じ挿入操作の別のパラメータとして再利用することができません。

    以下の例は、このテーブル定義に基づいています。

        CREATE MULTISET TABLE test01 (
          a1 INTEGER GENERATED BY DEFAULT AS IDENTITY
             (START WITH 1
              INCREMENT BY 20
              MAXVALUE 1000
             ),
          a2 INTEGER);
           

    以下のINSERT文は、Teradata Parallel Data Pumpフィールド変数を再使用しているため、失敗します。

        .LAYOUT layoutname;
        .FIELD uc1 INTEGER;
        .FIELD uc2 INTEGER;
        .DML LABEL labelname;
    
        INSERT INTO test01 VALUES (:uc1, :uc1);
           
        .LAYOUT layoutname;
        .FIELD uc1 INTEGER;
        .FIELD uc2 INTEGER;
        .DML LABEL labelname;
    
        INSERT INTO test01 VALUES (:uc2, (:uc2 + :uc2));

    以下のINSERT文は、Teradata Parallel Data Pumpフィールド変数を再使用しないため、成功します。

        .LAYOUT layoutname;
        .FIELD uc1 INTEGER;
        .FIELD uc2 INTEGER;
        .DML LABEL labelname;
    
        INSERT INTO test01 VALUES (:uc1, :uc2);
           
        .LAYOUT layoutname;
        .FIELD uc1 INTEGER;
        .FIELD uc2 INTEGER;
        .DML LABEL labelname;
    
        INSERT INTO test01 VALUES (:uc2, (:uc1 + :uc1));
           
  • Teradata Parallel Data Pumpを使用するGENERATED BY DEFAULT識別列へのINSERT操作では、識別列に挿入する値を算出する式にTeradata Parallel Data Pumpフィールド変数が含まれる場合、そのようなフィールド変数の指定はできません。
  • Teradata Parallel Data Pumpフィールド変数を使用してGENERATED BY DEFAULTおよびGENERATED ALWAYSの識別列に挿入する操作では、複数の識別列テーブルの識別列には挿入できません。
  • 非パーティションNoPIテーブルには識別列を指定できませんが、列パーティション テーブルには識別列を指定できます。
GENERATED … AS IDENTITYキーワードでは、以下のことを指定する句を定義します。
  • 列は、識別列である。
  • 新規行がテーブルに挿入されるとき、Teradata Databaseは列の値を生成する。ただし、後で説明する特定のケースは例外です。
GENERATED 説明
ALWAYS テーブルに新規行が挿入され、NO CYCLEが指定されている場合には、Teradata Databaseは列に対して固有値を常に生成します。

識別列テーブルに同じ行を2回ロードする場合、識別列値が生成された時点でその行は固有になるため、その行は重複として拒否しないことに注意する必要があります。実際に固有性が問題となる場合は、識別列テーブルにロードする行に対し、ある程度の事前処理を実行する必要があります。

BY DEFAULT INSERT文で列値が指定されていない場合に限り、テーブルに新規行が挿入されるときにTeradata Databaseは列に対して固有値を生成します。

生成される値が生成される値のセット内で必ず固有になるのは、NO CYCLEオプションを指定した場合だけです。

識別列の目的 オプション
UPI、USI、PK、またはその他のいくつかの行の固有性を保証します。 ALWAYS … NO CYCLE
  • テーブルにデータをロードするかテーブルからデータをアンロードします。
  • 1つのテーブルから別のテーブルに行をコピーします。
  • 順序におけるギャップを埋めます。
  • 現在削除されている行に以前属していた番号を再使用します。
BY DEFAULT
  • Teradata Unityはバルク データロードについては識別列をサポートしません。Teradata Databaseが行を処理する順序がシステムによって異なるからです。すべてのシステムで同じ行に同じ識別値が割り当てられることは保証されません。また、Teradata Unityの決めた値を複数システムにわたって特定の行に割り当てることはできません(特に、識別列がテーブルのプライマリ インデックスである場合)。

    識別列がすでに存在するテーブルをTeradata Unityで実行する必要がある場合には、ALTER TABLE文を使用して識別列からIDENTITY属性を削除すれば十分です。列そのものやデータを削除する必要はありません。Teradata Vantage™ - SQLデータ定義言語-構文規則および例、B035-1144の「ALTER TABLE」を参照してください。