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 typcol
jeTIMESTAMP
.YEAR(col)
a typcol
jeTIMESTAMP
.- Dva sloupce oddílů definované
YEAR(col), MONTH(col)
a typcol
jeTIMESTAMP
. - Tři sloupce oddílů definované podle
YEAR(col), MONTH(col), DAY(col)
a typcol
jeTIMESTAMP
. - Čtyři sloupce oddílů definované podle
YEAR(col), MONTH(col), DAY(col), HOUR(col)
a typcol
jeTIMESTAMP
. SUBSTRING(col, pos, len)
a typcol
STRING
DATE_FORMAT(col, format)
a typcol
jeTIMESTAMP
.- Formáty kalendářních dat můžete používat pouze s následujícími vzory:
yyyy-MM
ayyyy-MM-dd-HH
. - V Databricks Runtime 10.4 LTS a vyšší můžete použít také následující vzor:
yyyy-MM-dd
.
- Formáty kalendářních dat můžete používat pouze s následujícími vzory:
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 1
kroku . Nelze zadat velikost 0
kroku .
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í 2
kroku 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 IDENTITY
mohou 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:
- Vytvořte tabulku se správným schématem, včetně definice sloupce identity a dalších vlastností tabulky.
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
sloupecADD
,REPLACE
aniCHANGE
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.