Bagikan melalui


Kolom yang dihasilkan oleh Delta Lake

Penting

Fitur ini ada di Pratinjau Publik.

Delta Lake mendukung kolom yang dihasilkan yang merupakan jenis kolom khusus yang nilainya dibuat secara otomatis berdasarkan fungsi yang ditentukan pengguna di atas kolom lain dalam tabel Delta. Saat Anda menulis ke tabel dengan kolom yang dihasilkan dan Anda tidak secara eksplisit menyediakan nilai untuknya, Delta Lake secara otomatis menghitung nilai. Misalnya, Anda dapat secara otomatis membuat kolom tanggal (untuk mempartisi tabel menurut tanggal) dari kolom tanda waktu; penulisan apa pun ke dalam tabel hanya perlu menentukan data untuk kolom tanda waktu. Namun, jika Anda secara eksplisit memberikan nilai untuknya, nilai harus memenuhi batasan (<value> <=> <generation expression>) IS TRUE atau penulisan akan gagal dengan kesalahan.

Penting

Tabel yang dibuat dengan kolom yang dihasilkan memiliki versi protokol penulis tabel yang lebih tinggi daripada default. Lihat Bagaimana Azure Databricks mengelola kompatibilitas fitur Delta Lake? untuk memahami penerapan versi protokol tabel dan apa artinya memiliki versi protokol tabel yang lebih tinggi.

Membuat tabel dengan kolom yang dihasilkan

Contoh berikut menunjukkan cara membuat tabel dengan kolom yang dihasilkan:

SQL

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
)

Python

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()

Scala

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()

Kolom yang dihasilkan disimpan seolah-olah kolom tersebut adalah kolom normal. Artinya, mereka menempati penyimpanan.

Pembatasan berikut berlaku untuk kolom yang dihasilkan:

  • Ekspresi pembuatan dapat menggunakan fungsi SQL apa pun di Spark yang selalu mengembalikan hasil yang sama saat diberi nilai argumen yang sama, kecuali jenis fungsi berikut:
    • Fungsi yang ditentukan pengguna.
    • Fungsi agregat.
    • Fungsi jendela.
    • Fungsi mengembalikan beberapa baris.

Delta Lake dapat menghasilkan filter partisi untuk kueri setiap kali kolom partisi ditentukan oleh salah satu ekspresi berikut:

Catatan

Photon diperlukan dalam Databricks Runtime 10.4 LTS ke bawah. Photon tidak diperlukan dalam Databricks Runtime 11.3 LTS ke atas.

  • CAST(col AS DATE) dan jenisnya col adalah TIMESTAMP.
  • YEAR(col) dan jenisnya col adalah TIMESTAMP.
  • Dua kolom partisi yang ditentukan oleh YEAR(col), MONTH(col) dan jenis col adalah TIMESTAMP.
  • Tiga kolom partisi yang ditentukan oleh YEAR(col), MONTH(col), DAY(col) dan jenis dari col adalah TIMESTAMP.
  • Empat kolom partisi yang ditentukan oleh YEAR(col), MONTH(col), DAY(col), HOUR(col) dan jenis col adalah TIMESTAMP.
  • SUBSTRING(col, pos, len) dan jenis col adalah STRING
  • DATE_FORMAT(col, format) dan jenisnya col adalah TIMESTAMP.
    • Anda hanya dapat menggunakan format tanggal dengan pola berikut: yyyy-MM dan yyyy-MM-dd-HH.
    • Di Databricks Runtime 10.4 LTS ke atas, Anda juga dapat menggunakan pola berikut: yyyy-MM-dd.

Jika kolom partisi ditentukan oleh salah satu ekspresi sebelumnya, dan kueri memfilter data menggunakan kolom dasar yang mendasari ekspresi generasi, Delta Lake melihat hubungan antara kolom dasar dan kolom yang dihasilkan, dan mengisi filter partisi berdasarkan kolom partisi yang dihasilkan jika memungkinkan. Misalnya, dengan tabel berikut:

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

Jika Anda kemudian menjalankan kueri berikut:

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

Delta Lake secara otomatis menghasilkan filter partisi sehingga kueri sebelumnya hanya membaca data dalam partisi date=2020-10-01 meskipun filter partisi tidak ditentukan.

Sebagai contoh lain, dengan tabel berikut:

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)

Jika Anda kemudian menjalankan kueri berikut:

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

Delta Lake secara otomatis menghasilkan filter partisi sehingga kueri sebelumnya hanya membaca data dalam partisi year=2020/month=10/day=01 meskipun filter partisi tidak ditentukan.

Anda dapat menggunakan klausa EXPLAIN dan memeriksa rencana yang disediakan untuk melihat apakah Delta Lake secara otomatis menghasilkan filter partisi apa pun.

Menggunakan kolom identitas di Delta Lake

Penting

Mendeklarasikan kolom identitas pada tabel Delta menonaktifkan transaksi bersamaan. Hanya gunakan kolom identitas dalam kasus penggunaan di mana penulisan bersamaan ke tabel target tidak diperlukan.

Kolom identitas Delta Lake adalah jenis kolom yang dihasilkan yang menetapkan nilai unik untuk setiap rekaman yang disisipkan ke dalam tabel. Contoh berikut menunjukkan sintaks dasar untuk mendeklarasikan kolom identitas selama pernyataan buat tabel:

SQL

CREATE TABLE table_name (
  id_col1 BIGINT GENERATED ALWAYS AS IDENTITY,
  id_col2 BIGINT GENERATED ALWAYS AS IDENTITY (START WITH -1 INCREMENT BY 1),
  id_col3 BIGINT GENERATED BY DEFAULT AS IDENTITY,
  id_col4 BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH -1 INCREMENT BY 1)
 )

Python

from delta.tables import DeltaTable, IdentityGenerator
from pyspark.sql.types import LongType

DeltaTable.create()
  .tableName("table_name")
  .addColumn("id_col1", dataType=LongType(), generatedAlwaysAs=IdentityGenerator())
  .addColumn("id_col2", dataType=LongType(), generatedAlwaysAs=IdentityGenerator(start=-1, step=1))
  .addColumn("id_col3", dataType=LongType(), generatedByDefaultAs=IdentityGenerator())
  .addColumn("id_col4", dataType=LongType(), generatedByDefaultAs=IdentityGenerator(start=-1, step=1))
  .execute()

Scala

import io.delta.tables.DeltaTable
import org.apache.spark.sql.types.LongType

DeltaTable.create(spark)
  .tableName("table_name")
  .addColumn(
    DeltaTable.columnBuilder(spark, "id_col1")
      .dataType(LongType)
      .generatedAlwaysAsIdentity().build())
  .addColumn(
    DeltaTable.columnBuilder(spark, "id_col2")
      .dataType(LongType)
      .generatedAlwaysAsIdentity(start = -1L, step = 1L).build())
  .addColumn(
    DeltaTable.columnBuilder(spark, "id_col3")
      .dataType(LongType)
      .generatedByDefaultAsIdentity().build())
  .addColumn(
    DeltaTable.columnBuilder(spark, "id_col4")
      .dataType(LongType)
      .generatedByDefaultAsIdentity(start = -1L, step = 1L).build())
  .execute()

Catatan

API Scala dan Python untuk kolom identitas tersedia di Databricks Runtime 16.0 ke atas.

Untuk melihat semua opsi sintaks SQL untuk membuat tabel dengan kolom identitas, lihat CREATE TABLE [USING].

Anda dapat secara opsional menentukan hal berikut:

  • Nilai awal.
  • Ukuran langkah, yang bisa positif atau negatif.

Nilai awal dan ukuran langkah default ke 1. Anda tidak dapat menentukan ukuran 0langkah .

Nilai yang ditetapkan oleh kolom identitas bersifat unik dan bertambah ke arah langkah yang ditentukan, dan dalam kelipatan ukuran langkah yang ditentukan, tetapi tidak dijamin berdampingan. Misalnya, dengan nilai awal 0 dan ukuran langkah 2, semua nilai adalah angka genap positif, meskipun beberapa angka genap mungkin dilewati.

Saat menggunakan klausa GENERATED BY DEFAULT AS IDENTITY, operasi sisipkan dapat menentukan nilai untuk kolom identitas. Ubah klausul menjadi GENERATED ALWAYS AS IDENTITY untuk mengambil alih kemampuan untuk mengatur nilai secara manual.

Kolom identitas hanya mendukung jenis BIGINT, dan operasi gagal jika nilai yang ditetapkan melebihi rentang yang didukung oleh BIGINT.

Untuk mempelajari tentang menyinkronkan nilai kolom identitas dengan data, lihat ALTER TABLE ... klausa COLUMN.

Kolom CTAS dan kolom identitas

Anda tidak dapat menentukan skema, batasan kolom identitas, atau spesifikasi tabel lainnya saat menggunakan pernyataan CREATE TABLE table_name AS SELECT (CTAS).

Untuk membuat tabel baru dengan kolom identitas dan mengisinya dengan data yang sudah ada, lakukan hal berikut:

  1. Buat tabel dengan skema yang benar, termasuk definisi kolom identitas dan properti tabel lainnya.
  2. Jalankan INSERT operasi.

Contoh berikut menggunakan kata kunci DEFAULT untuk menentukan kolom identitas. Jika data yang disisipkan ke dalam tabel menyertakan nilai yang valid untuk kolom identitas, nilai-nilai ini digunakan.

CREATE OR REPLACE TABLE new_table (
  id BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 5),
  event_date DATE,
  some_value BIGINT
);

-- Inserts records including existing IDs
INSERT INTO new_table
SELECT id, event_date, some_value FROM old_table;

-- Insert records and generate new IDs
INSERT INTO new_table
SELECT event_date, some_value FROM new_records;

Batasan kolom identitas

Batasan berikut ada saat bekerja dengan kolom identitas:

  • Transaksi bersamaan tidak didukung pada tabel dengan kolom identitas diaktifkan.
  • Anda tidak dapat mempartisi tabel menurut kolom identitas.
  • Anda tidak dapat menggunakan ALTER TABLE untuk ADD, REPLACE, atau CHANGE kolom identitas.
  • Anda tidak dapat memperbarui nilai kolom identitas untuk rekaman yang sudah ada.

Catatan

Untuk mengubah IDENTITY nilai untuk rekaman yang sudah ada, Anda harus menghapus rekaman dan INSERT sebagai rekaman baru.