Sloupce generované Delta Lake

Important

Tato funkce je ve verzi Public Preview.

Vygenerované sloupce Delta Lake automaticky vypočítá a ukládají hodnoty z uživatelem definovaného výrazu přes ostatní sloupce v tabulce. Při zápisu do tabulky bez zadání hodnot pro vygenerované sloupce je Delta Lake vypočítá automaticky. Pokud zadáte hodnoty, musí být splněny (<value> <=> <generation expression>) IS TRUE nebo zápis selže. Viz Omezení v Azure Databricks.

Můžete například vypočítat sloupec price_with_tax z base_price * 1.1, aniž by bylo nutné, aby zápisy zadávaly data pro price_with_tax.

Stejně jako běžné sloupce jsou generované sloupce fyzicky uložené v podkladových datových souborech tabulky.

Note

Povolením vygenerovaných sloupců se upgraduje protokol zápisu tabulek. To může mít vliv na kompatibilitu s externími klienty Delta Lake. Viz kompatibilita a protokoly funkcí Delta Lake.

Vytvoření tabulky s vygenerovanými sloupci

Následující příklad ukazuje, jak vytvořit tabulku s vygenerovanými sloupci:

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

Podporované výrazy

Výraz generování může použít libovolnou deterministickou funkci SQL, která vždy vrátí stejný výsledek pro stejné vstupy. Příklad:

  • Aritmetika: base_price * 1.1
  • Řetězcové funkce: CONCAT(first_name, ' ', last_name), SUBSTRING(col, 1, 3)
  • Funkce data a času: CAST(birthDate AS DATE), YEAR(eventTime)

Následující typy funkcí nejsou podporovány:

  • Uživatelem definované funkce
  • Agregační funkce
  • Funkce okna
  • Funkce vracející více řádků

Generování filtru pro oddíl

Note

Databricks doporučuje pro všechny nové tabulky Delta Lake používat liquid clustering. Viz Použití metody 'liquid clustering' pro tabulky.

Když tabulku rozdělíte pomocí vygenerovaného sloupce a při dotazování základního sloupce, Delta Lake automaticky odvodí filtry oddílů, je-li to možné. Není nutné explicitně filtrovat podle vygenerovaného sloupce oddílu. Delta Lake odvodí rozsah oddílů od hodnoty základního sloupce.

Photon se vyžaduje v Databricks Runtime 10.4 LTS a níže. Photon není vyžadován v Databricks Runtime 11.3 LTS a novější.

Generování filtru partic je podporováno pro následující výrazy:

  • CAST(col AS DATE) a typ col je TIMESTAMP.
  • YEAR(col) a typ col je TIMESTAMP.
  • Dva oddílové sloupce definované pomocí YEAR(col), MONTH(col) a typ col je TIMESTAMP.
  • Tři sloupce oddílů definované podle YEAR(col), MONTH(col), DAY(col) a jejich typ col je TIMESTAMP.
  • Čtyři sloupce oddílů jsou definovány pomocí YEAR(col), MONTH(col), DAY(col), HOUR(col) a typ col je TIMESTAMP.
  • SUBSTRING(col, pos, len) a typ col je STRING
  • DATE_FORMAT(col, format) a typ col je TIMESTAMP.
    • Formáty kalendářních dat můžete používat pouze s následujícími vzory: yyyy-MM a yyyy-MM-dd-HH.
    • V Databricks Runtime 10.4 LTS a vyšší můžete použít také následující vzor: yyyy-MM-dd.

Příklad: jeden oddíl

Například v následující tabulce:

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

Pokud pak spustíte následující dotaz:

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

Delta Lake automaticky vygeneruje filtr oddílů tak, aby předchozí dotaz načetl pouze data v oddílu date=2020-10-01 i v případě, že není zadaný filtr oddílu.

Použijte klauzuli EXPLAIN a zkontrolujte poskytnutý plán, abyste zjistili, zda Delta Lake automaticky generuje filtry pro oddíly.

Příklad: více oddílů

Například v následující tabulce:

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)

Pokud pak spustíte následující dotaz:

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

Delta Lake automaticky vygeneruje filtr oddílů tak, aby předchozí dotaz načetl pouze data v oddílu year=2020/month=10/day=01 i v případě, že není zadaný filtr oddílu.

Použijte klauzuli EXPLAIN a zkontrolujte poskytnutý plán, abyste zjistili, zda Delta Lake automaticky generuje filtry particí.

Sloupce identit

Important

Deklarace sloupce identity v tabulce Delta Lake zakáže souběžné transakce. Sloupce identity používejte jenom v případech, kdy nejsou vyžadovány souběžné zápisy do cílové tabulky. Viz Omezení sloupců identit.

Sloupce identity Delta Lake jsou typ vygenerovaného sloupce, který přiřazuje jedinečné hodnoty pro každý záznam vložený do tabulky. Následující příklad ukazuje základní syntaxi pro deklarování sloupce identity během příkazu create table:

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

Rozhraní SCALA a Python API pro sloupce identit jsou k dispozici v Databricks Runtime 16.0 a novějších.

Pokud chcete zobrazit všechny možnosti syntaxe SQL pro vytváření tabulek se sloupci identit, přečtěte si CREATE TABLE [USING].

Volitelně můžete zadat následující:

  • Počáteční hodnota.
  • Velikost kroku, která může být kladná nebo záporná.

Výchozí hodnota i velikost kroku jsou nastaveny na 1 jako výchozí. Nelze zadat velikost 0kroku .

Hodnoty přiřazené sloupci identity jsou jedinečné a přírůstkové ve směru zadaného kroku a v násobcích zadané velikosti kroku, ale nejsou zaručeny souvislé. Například při počáteční hodnotě 0 a velikosti kroku 2jsou všechny hodnoty kladná sudá čísla, ale některá sudá čísla můžou být vynechána.

Při použití klauzule GENERATED BY DEFAULT AS IDENTITYmohou operace vložení zadat hodnoty sloupce identity. Upravte klauzuli tak, aby byla GENERATED ALWAYS AS IDENTITY, aby se přepsala možnost ručního nastavení hodnot.

Sloupce identity podporují pouze typ BIGINT a operace selžou, pokud přiřazená hodnota překročí rozsah podporovaný BIGINT.

Další informace o synchronizaci hodnot sloupců identity s daty najdete v ALTER TABLE klauzuli ... COLUMN.

Sloupce CTAS a identit

Při použití příkazu CREATE TABLE table_name AS SELECT (CTAS) nelze definovat schéma, omezení sloupců identit ani žádné jiné specifikace tabulky.

Pokud chcete vytvořit novou tabulku se sloupcem identity a naplnit ji existujícími daty, postupujte takto:

  1. Vytvořte tabulku se správným schématem, včetně definice sloupce identity a dalších vlastností tabulky.
  2. Spusťte operaci INSERT.

Následující příklad používá klíčové slovo DEFAULT k definování sloupce identity. Pokud data vložená do tabulky obsahují platné hodnoty pro sloupec identity, použijí se tyto hodnoty.

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;

Omezení sloupce identity

Při práci se sloupci identit existují následující omezení:

  • Souběžné transakce nejsou podporovány u tabulek s povolenými sloupci identit.
  • Tabulku nelze rozdělit podle sloupce identity.
  • Nemůžete použít ALTER TABLE k ADD, REPLACE ani CHANGE sloupce identity.
  • Nelze aktualizovat hodnotu sloupce identity pro existující záznam.

Note

Pokud chcete změnit IDENTITY hodnotu existujícího záznamu, musíte záznam odstranit a INSERT jako nový záznam.

Generované sloupce a masky sloupců

Vygenerovaný sloupec nemůže odkazovat na sloupec, který má použitou masku sloupce, protože vygenerovaná hodnota by odhalila podkladová data, která maska chrání. Tím dojde k chybě a dotaz selže. Viz filtry řádků a masky sloupců.

Tady jsou příklady chyb:

Pokud chcete všechny tyto chyby vyřešit, musíte přepracovat tabulku tak, aby se generované sloupce a maskované sloupce nepřekrývaly.