Delta Lake által létrehozott oszlopok

Important

Ez a funkció nyilvános előzetes verzióban van.

A Delta Lake által létrehozott oszlopok automatikusan kiszámítják és tárolják a felhasználó által definiált kifejezések értékeit a tábla más oszlopaiban. Ha úgy ír egy táblába, hogy nem ad meg értékeket a létrehozott oszlopokhoz, a Delta Lake automatikusan kiszámítja őket. Ha értékeket ad meg, azoknak meg kell felelniük (<value> <=> <generation expression>) IS TRUE , vagy az írás sikertelen. Lásd Korlátozások az Azure Databricksben.

Például kiszámíthat egy price_with_tax oszlopot a base_price * 1.1 alapján anélkül, hogy az írási műveletek során meg kellene adni a(z) price_with_tax adatait.

A normál oszlopokhoz hasonlóan a létrehozott oszlopok fizikailag a tábla alapjául szolgáló adatfájlokban vannak tárolva.

Note

A létrehozott oszlopok engedélyezése frissíti a táblaíró protokollt. Ez hatással lehet a külső Delta Lake-ügyfelekkel való kompatibilitásra. Lásd a Delta Lake szolgáltatáskompatibilitását és protokolljait.

Tábla létrehozása generált oszlopokkal

Az alábbi példa bemutatja, hogyan hozhat létre létrehozott oszlopokat tartalmazó táblát:

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

Támogatott kifejezések

A generációs kifejezések bármilyen determinisztikus SQL-függvényt használhatnak, amely mindig ugyanazt az eredményt adja vissza ugyanazokhoz a bemenetekhez. Például:

  • Aritmetika: base_price * 1.1
  • Sztringfüggvények: CONCAT(first_name, ' ', last_name), SUBSTRING(col, 1, 3)
  • Dátumfüggvények: CAST(birthDate AS DATE), YEAR(eventTime)

A következő függvénytípusok nem támogatottak:

  • Felhasználó által definiált függvények
  • Összesítő függvények
  • Ablakfunkciók
  • Több sort visszaadó függvények

Partíciószűrő létrehozása

Note

A Databricks a liquid clustering használatát javasolja minden új Delta Lake-táblához. Lásd: Táblákhoz folyékony klaszterezés használata.

Amikor egy táblát egy generált oszlop és lekérdezés használatával particionál az alaposzlopon, a Delta Lake automatikusan kinyeri a partíciószűrőket, ha lehetséges. Nem kell explicit módon szűrést alkalmaznia a generált partícióoszlop alapján. A Delta Lake az alaposzlop értékéből következtet a partíciótartományra.

A Databricks Runtime 10.4 LTS-ben és az alábbi verziókban foton szükséges. A Databricks Runtime 11.3 LTS-ben és újabb verziókban nem szükséges foton.

A partíciószűrő létrehozása a következő kifejezések esetében támogatott:

  • CAST(col AS DATE) és a típus col az TIMESTAMP.
  • YEAR(col) és a típus col az TIMESTAMP.
  • A YEAR(col), MONTH(col) által definiált két partícióoszlop és a col típusa TIMESTAMP.
  • A YEAR(col), MONTH(col), DAY(col) által definiált három partícióoszlop és a col típusa TIMESTAMP.
  • A YEAR(col), MONTH(col), DAY(col), HOUR(col) által definiált négy partícióoszlop és a col típusa TIMESTAMP.
  • SUBSTRING(col, pos, len) és a(z) col típusa STRING
  • DATE_FORMAT(col, format) és a típus col az TIMESTAMP.
    • Dátumformátumokat csak a következő mintákkal használhat: yyyy-MM és yyyy-MM-dd-HH.
    • A Databricks Runtime 10.4 LTS és újabb verziókban a következő mintát is használhatja: yyyy-MM-dd.

Példa: egyetlen partíció

Például a következő táblázat alapján:

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

Ha ezután a következő lekérdezést futtatja:

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

A Delta Lake automatikusan létrehoz egy partíciószűrőt, így az előző lekérdezés csak akkor olvassa be az adatokat a partíció date=2020-10-01, ha nincs megadva partíciószűrő.

Használjon záradékot EXPLAIN , és ellenőrizze a megadott tervet, hogy a Delta Lake automatikusan létrehoz-e partíciószűrőket.

Példa: több partíció

Például a következő táblázat alapján:

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)

Ha ezután a következő lekérdezést futtatja:

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

A Delta Lake automatikusan létrehoz egy partíciószűrőt, így az előző lekérdezés csak akkor olvassa be az adatokat a partíció year=2020/month=10/day=01, ha nincs megadva partíciószűrő.

Használjon záradékot EXPLAIN , és ellenőrizze a megadott tervet, hogy a Delta Lake automatikusan létrehoz-e partíciószűrőket.

Identitásoszlopok

Important

Ha egy identitásoszlopot deklarál egy Delta Lake-táblában, az letiltja az egyidejű tranzakciókat. Csak olyan esetekben használjon identitásoszlopokat, amikor nincs szükség egyidejű írásra a céltáblába. Lásd : Identitásoszlopokra vonatkozó korlátozások.

A Delta Lake-identitásoszlopok olyan generált oszloptípusok, amelyek egyedi értékeket rendelnek a táblába beszúrt rekordokhoz. Az alábbi példa egy identitásoszlop deklarálásának alapszintaxisát mutatja be egy tábla-létrehozási utasítás során:

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

Note

Az identitásoszlopokhoz készült Scala és Python API-k a Databricks Runtime 16.0-s és újabb verziókban érhetők el.

Az identitásoszlopokkal rendelkező táblák létrehozásához használható ÖSSZES SQL-szintaxisi beállítás megtekintéséhez lásd: CREATE TABLE [USING].

Opcionálisan megadhatja a következőket:

  • Kezdőérték.
  • Egy lépésméret, amely lehet pozitív vagy negatív.

A kezdőérték és a lépésméret alapértelmezés szerint a következő lesz 1: . Nem lehet lépésméretet 0 megadni.

Az identitásoszlopok által hozzárendelt értékek egyediek, és a megadott lépés irányában és a megadott lépésméret többszörösében növeksenek, de nem garantált, hogy egybefüggőek. Például 0 kezdőértékkel és 2lépésmérettel minden érték pozitív páros szám, de egyes páros számok kihagyhatók.

A GENERATED BY DEFAULT AS IDENTITYzáradék használatakor a beszúrási műveletek megadhatják az identitásoszlop értékeit. Módosítsa a záradékot úgy, hogy GENERATED ALWAYS AS IDENTITY legyen, hogy felülbírálja az értékek manuális beállításának képességét.

Az identitásoszlopok csak a BIGINT típust támogatják, és a műveletek meghiúsulnak, ha a hozzárendelt érték meghaladja a BIGINTáltal támogatott tartományt.

Az identitásoszlop értékeinek adatokkal való szinkronizálásáról a ... ALTER TABLE záradékban olvashatCOLUMN.

CTAS- és identitásoszlopok

A CREATE TABLE table_name AS SELECT (CTAS) utasítás használatakor nem definiálhat sémát, identitásoszlop-korlátozásokat vagy más táblaspecifikációkat.

Ha identitásoszlopot tartalmazó új táblát szeretne létrehozni, és meglévő adatokkal szeretné feltölteni, tegye a következőket:

  1. Hozzon létre egy táblázatot a megfelelő sémával, beleértve az identitásoszlop definícióját és más táblatulajdonságokat.
  2. Futtass INSERT műveletet.

Az alábbi példa a DEFAULT kulcsszóval határozza meg az identitásoszlopot. Ha a táblázatba beszúrt adatok az identitásoszlop érvényes értékeit tartalmazzák, akkor ezeket az értékeket használja a rendszer.

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 (id, event_date, some_value)
SELECT id, event_date, some_value FROM old_table;

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

Identitásoszlop korlátozásai

Az identitásoszlopok használatakor a következő korlátozások vonatkoznak:

  • Az egyidejű tranzakciók nem támogatottak az identitásoszlopokat engedélyező táblákban.
  • Egy tábla nem particionálható identitásoszlop alapján.
  • Nem használhatja a(z) ALTER TABLE, ADD, REPLACE vagy CHANGE műveletet identitásoszlopon.
  • Egy meglévő rekord identitásoszlopának értéke nem frissíthető.

Note

Egy meglévő rekord értékének IDENTITY módosításához törölnie kell a rekordot és INSERT azt új rekordként.

Létrehozott oszlopok és oszlopmaszkok

A létrehozott oszlopok nem hivatkozhatók oszlopmaszkkal rendelkező oszlopokra, mert a létrehozott érték felfedi a maszk által védett mögöttes adatokat. Ez hibát okoz, és a lekérdezés meghiúsul. Lásd: Sorszűrők és oszlopmaszkok.

Íme néhány példa a hibákra:

Az összes hiba megoldásához úgy kell újraterveznie a táblát, hogy a létrehozott és maszkolt oszlopok ne fedjék egymást.