Kolom yang dihasilkan 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 memberikan nilai untuknya, Delta Lake secara otomatis menghitung nilainya. Misalnya, Anda dapat secara otomatis membuat kolom tanggal (untuk mempartisi tabel berdasarkan tanggal) dari kolom stempel waktu; setiap tulisan ke dalam tabel hanya perlu menentukan data untuk kolom stempel 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 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 jenisnyacol
adalahTIMESTAMP
.YEAR(col)
dan jenisnyacol
adalahTIMESTAMP
.- Dua kolom partisi ditentukan oleh
YEAR(col), MONTH(col)
dan jeniscol
adalahTIMESTAMP
. - Tiga kolom partisi ditentukan oleh
YEAR(col), MONTH(col), DAY(col)
dan jeniscol
adalahTIMESTAMP
. - Empat kolom partisi ditentukan oleh
YEAR(col), MONTH(col), DAY(col), HOUR(col)
dan jeniscol
adalahTIMESTAMP
. SUBSTRING(col, pos, len)
dan jeniscol
adalahSTRING
DATE_FORMAT(col, format)
dan jenisnyacol
adalahTIMESTAMP
.- Anda hanya dapat menggunakan format tanggal dengan pola berikut:
yyyy-MM
danyyyy-MM-dd-HH
. - Di Databricks Runtime 10.4 LTS ke atas, Anda juga dapat menggunakan pola berikut:
yyyy-MM-dd
.
- Anda hanya dapat menggunakan format tanggal dengan pola berikut:
Jika kolom partisi ditentukan oleh salah satu ekspresi sebelumnya, dan kueri memfilter data menggunakan kolom dasar yang mendasari ekspresi pembuatan, Delta Lake melihat hubungan antara kolom dasar dan kolom yang dihasilkan, dan mengisi filter partisi berdasarkan kolom partisi yang dihasilkan jika memungkinkan. Misalnya diberikan tabel berikut ini:
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 membuat filter partisi sehingga kueri sebelumnya hanya membaca data di partisi date=2020-10-01
meskipun filter partisi tidak ditentukan.
Sebagai contoh lain, diberikan 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 membuat filter partisi sehingga kueri sebelumnya hanya membaca data di partisi year=2020/month=10/day=01
meskipun filter partisi tidak ditentukan.
Anda dapat menggunakan klausul MENJELASKAN dan memeriksa paket yang disediakan untuk melihat apakah Delta Lake membuat filter partisi secara otomatis.
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 0
langkah .
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 0
awal dan ukuran 2
langkah , semua nilai adalah angka genap positif tetapi beberapa angka genap mungkin dilewati.
Saat menggunakan klausa GENERATED BY DEFAULT AS IDENTITY
, operasi sisipkan dapat menentukan nilai untuk kolom identitas. Ubah klausa untuk GENERATED ALWAYS AS IDENTITY
mengambil alih kemampuan untuk mengatur nilai secara manual.
Kolom identitas hanya mendukung BIGINT
jenis, 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 identitas
Anda tidak dapat menentukan skema, batasan kolom identitas, atau spesifikasi tabel lainnya saat menggunakan CREATE TABLE table_name AS SELECT
pernyataan (CTAS).
Untuk membuat tabel baru dengan kolom identitas dan mengisinya dengan data yang sudah ada, lakukan hal berikut:
- Buat tabel dengan skema yang benar, termasuk definisi kolom identitas dan properti tabel lainnya.
- Jalankan
INSERT
operasi.
Contoh berikut menggunakan DEFAULT
kata kunci 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
untukADD
,REPLACE
, atauCHANGE
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.