Megosztás a következőn keresztül:


Delta Lake által létrehozott oszlopok

Fontos

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

A Delta Lake támogatja a létrehozott oszlopokat, amelyek olyan speciális típusú oszlopok, amelyek értékei automatikusan létrejönnek egy felhasználó által megadott függvény alapján a Delta tábla más oszlopai felett. Amikor létrehozott oszlopokat tartalmazó táblába ír, és nem ad meg explicit módon értékeket, a Delta Lake automatikusan kiszámítja az értékeket. Létrehozhat például egy dátumoszlopot (a tábla dátum szerinti particionálásához) az időbélyeg oszlopból; a táblába történő írásoknak csak az időbélyeg oszlop adatait kell megadniuk. Ha azonban explicit módon ad meg értékeket, az értékeknek meg kell felelniük a kényszernek(<value> <=> <generation expression>) IS TRUE, vagy az írás hiba miatt meghiúsul.

Fontos

A létrehozott oszlopokkal létrehozott táblák az alapértelmezettnél magasabb táblaíró protokollverzióval rendelkeznek. Lásd Hogyan kezeli az Azure Databricks a Delta Lake-funkciók kompatibilitását? a táblaprotokoll verziószámozásának megértéséhez, és azt, hogy mit jelent a táblaprotokoll-verzió magasabb szintű verziója.

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

A létrehozott oszlopok úgy vannak tárolva, mintha normál oszlopok lennének. Vagyis tárolót foglalnak el.

A létrehozott oszlopokra a következő korlátozások vonatkoznak:

  • A generációs kifejezések bármilyen SQL-függvényt használhatnak a Sparkban, amely ugyanazt az eredményt adja vissza ugyanazon argumentumértékek megadásakor, kivéve a következő függvénytípusokat:
    • Felhasználó által definiált függvények.
    • Összesítő függvények.
    • Ablakfüggvények.
    • Több sort visszaadó függvények.

A Delta Lake akkor tud partíciószűrőket létrehozni egy lekérdezéshez, ha egy partícióoszlopot az alábbi kifejezések valamelyike határoz meg:

Feljegyzés

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.

  • 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 típus a következő col : 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.

Ha egy partícióoszlopot az előző kifejezések egyike határoz meg, és egy lekérdezés egy generációs kifejezés alapjául szolgáló alaposzlop használatával szűri az adatokat, a Delta Lake megvizsgálja az alaposzlop és a létrehozott oszlop közötti kapcsolatot, és lehetőség szerint feltölti a partíciószűrőket a létrehozott partícióoszlop alapján. 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" <= "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ő.

Egy másik példaként az alábbi táblázatot tekintve:

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" <= "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álhat egy EXPLAIN záradékot, és ellenőrizheti a megadott tervet, hogy a Delta Lake automatikusan létrehoz-e partíciószűrőket.

Identitásoszlopok használata a Delta Lake-ben

Fontos

Ha egy identitásoszlopot deklarál egy Delta-táblában, azzal 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.

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

Feljegyzés

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: . A lépésméret 0nem határozható meg.

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 az ALTER TABLE ... COLUMN záradékcímű témakörben olvashat.

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. Futtasson egy 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
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;

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.
  • A táblák nem particionálhatók identitásoszlopok szerint.
  • Nem használhat ALTER TABLE identitásoszlopként a következőkkel: ADD, REPLACEvagy CHANGE.
  • Meglévő rekord identitásoszlopának értéke nem frissíthető.

Feljegyzés

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.