Sdílet prostřednictvím


Vygenerované sloupce Delta Lake

Důležité

Tato funkce je ve verzi Public Preview.

Delta Lake podporuje generované sloupce, které jsou speciálním typem sloupce, jehož hodnoty se automaticky generují na základě uživatelem zadané funkce nad jinými sloupci v tabulce Delta. Když zapíšete do tabulky s vygenerovanými sloupci a explicitně pro ně nezadáte hodnoty, Delta Lake hodnoty automaticky vypočítá. Můžete například automaticky vygenerovat sloupec kalendářního data (pro dělení tabulky podle data) ze sloupce časového razítka; Všechny zápisy do tabulky potřebují pouze data pro sloupec časového razítka. Pokud však explicitně zadáte hodnoty, musí tyto hodnoty splňovat omezení (<value> <=> <generation expression>) IS TRUE nebo zápis selže s chybou.

Důležité

Tabulky vytvořené s vygenerovanými sloupci mají vyšší verzi protokolu zápisu tabulek než výchozí. Podívejte se, jak Azure Databricks spravuje kompatibilitu funkcí Delta Lake? Abyste porozuměli správě verzí tabulkových protokolů a co to znamená, že máte vyšší verzi tabulkového protokolu.

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

Vygenerované sloupce se ukládají jako normální sloupce. To znamená, že zabírají úložiště.

Pro vygenerované sloupce platí následující omezení:

  • Výraz generování může použít všechny funkce SQL ve Sparku, které vždy vrátí stejný výsledek, pokud jsou zadané stejné hodnoty argumentů, s výjimkou následujících typů funkcí:
    • Uživatelem definované funkce.
    • Agregační funkce
    • Funkce oken.
    • Funkce vracející více řádků

Delta Lake může generovat filtry oddílů pro dotaz vždy, když je sloupec oddílu definovaný jedním z následujících výrazů:

Poznámka:

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 vyšší.

  • CAST(col AS DATE) a typ col je TIMESTAMP.
  • YEAR(col) a typ col je TIMESTAMP.
  • Dva sloupce oddílů definované YEAR(col), MONTH(col) a typ col je TIMESTAMP.
  • Tři sloupce oddílů definované podle YEAR(col), MONTH(col), DAY(col) a typ col je TIMESTAMP.
  • Čtyři sloupce oddílů definované podle YEAR(col), MONTH(col), DAY(col), HOUR(col) a typ col je TIMESTAMP.
  • SUBSTRING(col, pos, len)a typ colSTRING
  • 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.

Pokud je sloupec oddílu definovaný jedním z předchozích výrazů a dotaz filtruje data pomocí základního základního sloupce výrazu generování, Delta Lake se podívá na vztah mezi základním sloupcem a vygenerovaným sloupcem a pokud je to možné, naplní filtry oddílů na základě vygenerovaného sloupce oddílu. 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" <= "2020-10-01 12:00:00"

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

Jako další příklad je uvedena následující tabulka:

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" <= "2020-10-01 12:00:00"

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

Můžete použít klauzuli EXPLAIN a zkontrolovat zadaný plán, abyste zjistili, jestli Delta Lake automaticky generuje filtry oddílů.

Použití sloupců identit v Delta Lake

Důležité

Deklarace sloupce identity v tabulce Delta 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.

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

Poznámka:

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 téma 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 1kroku . 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 s počáteční hodnotou 0 a velikostí 2kroku jsou 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 pro sloupec identity. Upravte klauzuli tak, aby GENERATED ALWAYS AS IDENTITY přepsala možnost ručního nastavení hodnot.

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

Informace o synchronizaci hodnot sloupců identity s daty najdete v tématu ALTER TABLE ... KLAUZULE COLUMN.

Sloupce CTAS a identit

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

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. INSERT Spusťte operaci.

Následující příklad používá DEFAULT klíčové slovo 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
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;

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.
  • Nelze použít ALTER TABLE sloupec ADD, REPLACEani CHANGE sloupec identity.
  • Hodnotu sloupce identity pro existující záznam nelze aktualizovat.

Poznámka:

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