Delta Lake で生成されたカラム

プレビュー

この機能はパブリックプレビュー段階です。

Delta Lake では、Delta テーブル内の他の列に対するユーザー指定の関数に基づいて値が自動的に生成される特殊な型の列である生成列がサポートされています。 生成された列を持つテーブルに書き込むときに、それらの値を明示的に指定しない場合、Delta Lake は自動的に値を圧縮します。 たとえば、タイムスタンプ列から日付列 (テーブルを日付でパーティション分割するため) を自動的に生成できます。テーブルへの書き込みでは、タイムスタンプ列のデータを指定するだけで済みます。 ただし、明示的に値を指定する場合、値は 制約 (<value> <=> <generation expression>) IS TRUE を満たす必要があり、そうしないと書き込みがエラーで失敗します。

重要

生成された列で作成されたテーブルのテーブル ライター プロトコルのバージョンは、デフォルトよりも高くなります。 「 Databricks は Delta Lake 機能の互換性をどのように管理しますか?」 を参照してください。 テーブル プロトコルのバージョン管理と、テーブル プロトコルのバージョンを高くすることの意味を理解します。

生成列を含むテーブルを作成する

次の例は、生成された列を持つテーブルを作成する方法を示しています。

CREATE TABLE default.people10m (
  id INT,
  firstName STRING,
  middleName STRING,
  lastName STRING,
  gender STRING,
  birthDate TIMESTAMP,
  dateOfBirth DATE GENERATED ALWAYS AS (CAST(birthDate AS DATE)),
  ssn STRING,
  salary INT
)
DeltaTable.create(spark) \
  .tableName("default.people10m") \
  .addColumn("id", "INT") \
  .addColumn("firstName", "STRING") \
  .addColumn("middleName", "STRING") \
  .addColumn("lastName", "STRING", comment = "surname") \
  .addColumn("gender", "STRING") \
  .addColumn("birthDate", "TIMESTAMP") \
  .addColumn("dateOfBirth", DateType(), generatedAlwaysAs="CAST(birthDate AS DATE)") \
  .addColumn("ssn", "STRING") \
  .addColumn("salary", "INT") \
  .execute()
DeltaTable.create(spark)
  .tableName("default.people10m")
  .addColumn("id", "INT")
  .addColumn("firstName", "STRING")
  .addColumn("middleName", "STRING")
  .addColumn(
    DeltaTable.columnBuilder("lastName")
      .dataType("STRING")
      .comment("surname")
      .build())
  .addColumn("lastName", "STRING", comment = "surname")
  .addColumn("gender", "STRING")
  .addColumn("birthDate", "TIMESTAMP")
  .addColumn(
    DeltaTable.columnBuilder("dateOfBirth")
     .dataType(DateType)
     .generatedAlwaysAs("CAST(dateOfBirth AS DATE)")
     .build())
  .addColumn("ssn", "STRING")
  .addColumn("salary", "INT")
  .execute()

生成された列は、通常の列であるかのように格納されます。 つまり、それらはストレージを占有します。

生成される列には、次の制限が適用されます。

  • 生成式では、次の種類の関数を除き、同じ引数値が指定された場合に常に同じ結果を返す Spark の任意の SQL 関数を使用できます。

    • ユーザー定義関数。

    • 集計関数。

    • ウィンドウ関数。

    • 複数の行を返す関数。

Delta Lake では、パーティション列が次のいずれかの式で定義されている場合は常に、クエリーのパーティション フィルターを生成できます。

Databricks Runtime 10.4 LTS 以下では Photon が必要です。 Databricks Runtime 11.3 LTS 以降では Photon は必要ありません。

  • CAST(col AS DATE) そして col の種類は TIMESTAMPです.

  • YEAR(col) そして col の種類は TIMESTAMPです.

  • YEAR(col), MONTH(col) で定義された 2 つのパーティション列と col の種類は TIMESTAMPです。

  • YEAR(col), MONTH(col), DAY(col) によって定義される 3 つのパーティション列と col の種類は TIMESTAMPです。

  • YEAR(col), MONTH(col), DAY(col), HOUR(col) で定義される 4 つのパーティション列と col の種類は TIMESTAMPです。

  • SUBSTRING(col, pos, len) col の種類は STRING

  • DATE_FORMAT(col, format) そして col の種類は TIMESTAMPです.

    • 日付形式は、 yyyy-MMyyyy-MM-dd-HHのパターンでのみ使用できます。

    • Databricks Runtime 10.4 LTS 以降では、次のパターンを使用することもできますyyyy-MM-dd

パーティション列が上記の式のいずれかで定義され、クエリが生成式の基になる基本列を使用してデータをフィルター処理する場合、Delta Lake は基本列と生成された列の関係を調べ、可能であれば生成されたパーティション列に基づいてパーティション フィルターを設定します。 たとえば、次のテーブルがあるとします。

CREATE TABLE events(
eventId BIGINT,
data STRING,
eventType STRING,
eventTime TIMESTAMP,
eventDate date GENERATED ALWAYS AS (CAST(eventTime AS DATE))
)
PARTITIONED BY (eventType, eventDate)

次に、次のクエリーを実行するとします。

SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"

Delta Lake はパーティション フィルターを自動的に生成するため、パーティション フィルターが指定されていない場合でも、前のクエリはパーティション date=2020-10-01 内のデータのみを読み取ることができます。

別の例として、次のテーブルがあるとします。

CREATE TABLE events(
eventId BIGINT,
data STRING,
eventType STRING,
eventTime TIMESTAMP,
year INT GENERATED ALWAYS AS (YEAR(eventTime)),
month INT GENERATED ALWAYS AS (MONTH(eventTime)),
day INT GENERATED ALWAYS AS (DAY(eventTime))
)
PARTITIONED BY (eventType, year, month, day)

次に、次のクエリーを実行するとします。

SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"

Delta Lake はパーティション フィルターを自動的に生成するため、パーティション フィルターが指定されていない場合でも、前のクエリはパーティション year=2020/month=10/day=01 内のデータのみを読み取ることができます。

EXPLAIN 句を使用し、指定されたプランをチェックして、Delta Lake がパーティション フィルターを自動的に生成するかどうかを確認できます。

Delta Lake での ID 列の使用

重要

Delta テーブルで ID 列を宣言すると、並列トランザクションが無効になります。 ID 列は、ターゲット表への並列書き込みが不要なユース・ケースでのみ使用してください。

Delta Lake の ID 列は、テーブルに挿入された各レコードに一意の値を割り当てる生成列の一種です。 次の例は、CREATE TABLE ステートメント中に ID 列を宣言するための基本的な構文を示しています。

CREATE TABLE table_name (
  identity_col BIGINT GENERATED BY DEFAULT AS IDENTITY,
  other_column ...)

ID 列を含むテーブルを作成するためのすべての構文オプションを確認するには、 「 CREATE TABLE [USING] 」を参照してください。

オプションで、以下を指定できます。

  • 開始値。

  • ステップ サイズ。正または負の値を指定できます。

ID 列によって割り当てられる値は一意であり、指定されたステップの方向に、指定されたステップ サイズの倍数で増加しますが、連続していることは保証されません。 たとえば、開始値が0でステップ サイズが2の場合、すべての値は正の偶数ですが、一部の偶数はスキップされる可能性があります。

GENERATED BY DEFAULT AS IDENTITYを使用する場合、挿入操作で ID 列の値を指定できます。 GENERATED ALWAYS AS IDENTITYする句を変更して、値を手動で設定する機能をオーバーライドします。

ID 列は BIGINT 型のみをサポートし、割り当てられた値が BIGINTでサポートされている範囲を超えると、操作は失敗します。

ID 列の値をデータと同期する方法については、「 ALTER TABLE」を参照してください。

ID 列の制限

ID 列を処理する場合、以下の制限があります。

  • アイデンティティ列が有効になっているテーブルでは、トランザクションはサポートされません。

  • ID 列によって表をパーティション化することはできません。

  • ALTER TABLE を使用して ID 列ADDREPLACE、またはCHANGEすることはできません。

  • 既存のレコードの ID 列の値は更新できません。

既存のレコードの IDENTITY 値を変更するには、レコードを削除し、新しいレコードとして INSERT する必要があります。