Sloupce generované 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í. Navštivte Jak Azure Databricks spravuje kompatibilitu funkcí Delta Lake?, abyste zjistili, jak se spravují verze tabulkových protokolů a co znamená mít 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
- Okenní funkce.
- Funkce vracející více řádků
Delta Lake může generovat filtry pro oddíly pro dotaz vždy, když je sloupec oddílu definován některý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 oddílové sloupce definované pomocí
YEAR(col), MONTH(col)
a typcol
jeTIMESTAMP
. - Tři sloupce oddílů definované podle
YEAR(col), MONTH(col), DAY(col)
a jejich typcol
jeTIMESTAMP
. - Čtyři sloupce oddílů jsou definovány pomocí
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 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ů podle vygenerovaného oddílového sloupce. 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 načetl pouze data v oddílu date=2020-10-01
i v případě, že 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 načetl pouze data v oddílu year=2020/month=10/day=01
i v případě, že není zadaný filtr oddílu.
Můžete použít klauzuli EXPLAIN a zkontrolovat poskytnutý 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 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 při počáteční hodnotě 0
a velikosti kroku 2
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 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 viz ALTER TABLE ... COLUMN klauzule.
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:
- 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á 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
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
naADD
,REPLACE
aniCHANGE
pro 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.