Delta Lake genererad columns
Viktigt!
Den här funktionen finns som allmänt tillgänglig förhandsversion.
Delta Lake stöder genererade columns som är en särskild typ av column vars values genereras automatiskt baserat på en användardefinerad funktion jämfört med andra columns i Delta table. När du skriver till en table med genererade columns utan att uttryckligen ange values för dem, beräknar Delta Lake automatiskt values. Man kan till exempel automatiskt generate ett datum column (för att partitionera table efter datum) från tidsstämpeln column; alla skrivningar till table behöver bara ange data för tidsstämpeln column. Men om du uttryckligen anger values för dem måste values uppfylla constraint(<value> <=> <generation expression>) IS TRUE
, annars misslyckas skrivningen med ett fel.
Viktigt!
Tables som skapats med genererade columns har en högre table skrivprotokollversion än standardversionen. Se Hur hanterar Azure Databricks Delta Lake-funktionskompatibilitet? att förstå table protokollversioner och vad det innebär att ha en högre version av en table protokollversion.
Skapa en table med genererade columns
I följande exempel visas hur du skapar en table med genererade columns:
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()
Genererade columns lagras som om de vore normala columns. Det vill säger att de upptar lagring.
Följande begränsningar gäller för genererade columns:
- Ett generationsuttryck kan använda alla SQL-funktioner i Spark som alltid returnerar samma resultat när samma argument values, förutom följande typer av funktioner:
- Användardefinierade funktioner.
- Mängdfunktioner.
- Window funktioner.
- Funktioner som returnerar flera rader.
Delta Lake kan generatepartition filter för en sökfråga när en partitioncolumn definieras av något av följande uttryck:
Kommentar
Photon krävs i Databricks Runtime 10.4 LTS och nedan. Photon krävs inte i Databricks Runtime 11.3 LTS och senare.
-
CAST(col AS DATE)
och typen avcol
ärTIMESTAMP
. -
YEAR(col)
och typen avcol
ärTIMESTAMP
. - Två partitioncolumns definieras av
YEAR(col), MONTH(col)
och typen avcol
ärTIMESTAMP
. - Tre partitioncolumns definieras av
YEAR(col), MONTH(col), DAY(col)
och typen avcol
ärTIMESTAMP
. - Fyra partitioncolumns definieras av
YEAR(col), MONTH(col), DAY(col), HOUR(col)
och typen avcol
ärTIMESTAMP
. -
SUBSTRING(col, pos, len)
och typen avcol
ärSTRING
-
DATE_FORMAT(col, format)
och typen avcol
ärTIMESTAMP
.- Du kan bara använda datumformat med följande mönster:
yyyy-MM
ochyyyy-MM-dd-HH
. - I Databricks Runtime 10.4 LTS och senare kan du också använda följande mönster:
yyyy-MM-dd
.
- Du kan bara använda datumformat med följande mönster:
Om en partitioncolumn definieras av ett av ovanstående uttryck och en fråga filtrerar data med hjälp av den underliggande basen column för ett generationsuttryck, tittar Delta Lake på relationen mellan bas-column och den genererade columnoch fyller i partition filter baserat på den genererade partitioncolumn om möjligt. Till exempel med följande table:
CREATE TABLE events(
eventId BIGINT,
data STRING,
eventType STRING,
eventTime TIMESTAMP,
eventDate date GENERATED ALWAYS AS (CAST(eventTime AS DATE))
)
PARTITIONED BY (eventType, eventDate)
Om du sedan kör följande fråga:
SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"
Delta Lake genererar automatiskt ett partition filter så att föregående fråga endast läser data i partitiondate=2020-10-01
även om ett partition filter inte har angetts.
Som ett annat exempel, givet följande table:
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)
Om du sedan kör följande fråga:
SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"
Delta Lake genererar automatiskt ett partition filter så att föregående fråga endast läser data i partitionyear=2020/month=10/day=01
även om ett partition filter inte har angetts.
Du kan använda en EXPLAIN-sats och kontrollera den angivna planen för att se om Delta Lake automatiskt genererar några partition filter.
Använd identitet columns i Delta Lake
Viktigt!
Om du deklarerar en identitet column på en Delta-table inaktiveras samtidiga transaktioner. Använd endast identitet columns i användningsfall where där samtidiga skrivningar till målet table inte är nödvändiga.
Delta Lake-identitet columns är en typ av genererad column som tilldelar unika values för varje post som infogas i en table. I följande exempel visas den grundläggande syntaxen för att deklarera en identitet column i ett skapa-uttalande 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()
Kommentar
Scala- och Python-API:er för identitet columns är tillgängliga i Databricks Runtime 16.0 och senare.
Om du vill se alla SQL-syntaxalternativ för att skapa tables med identitet columnsläser du CREATE TABLE [USING].
Du kan också ange följande:
- Ett startvärde.
- En stegstorlek som kan vara positiv eller negativ.
Både startvärdet och stegstorleken är standardvärdet 1
. Du kan inte ange en stegstorlek på 0
.
Values som tilldelas av identitet columns är unika och ökar enligt det angivna steget och i multiplar av den angivna stegstorleken, men är inte garanterat sammanhängande. Med ett startvärde på 0
och en stegstorlek på 2
är alla values positiva jämna tal, men vissa jämna tal kan hoppas över.
När du använder satsen GENERATED BY DEFAULT AS IDENTITY
kan åtgärderna insert ange values för identiteten column. Ändra klausulen till GENERATED ALWAYS AS IDENTITY
för att åsidosätta möjligheten att manuellt setvalues.
Identiteten columns stöder endast BIGINT
-typ, och operationer misslyckas om det tilldelade värdet överskrider det intervall som stöds av BIGINT
.
För att lära dig om att synkronisera identitet columnvalues med data, se ALTER TABLE ... COLUMN klausul.
CTAS och identitet columns
Du kan inte definiera schema, identitetsbegränsningar column eller andra table specifikationer när du använder en CREATE TABLE table_name AS SELECT
-instruktion (CTAS).
Om du vill skapa en ny table med en identitet column och fylla den med befintliga data gör du följande:
- Skapa en table med rätt schema, inklusive identitetsdefinitionen column och andra egenskaper för table.
- Kör en
INSERT
åtgärd.
I följande exempel används nyckelordet DEFAULT
för att definiera identiteten column. Om data, som infogas i table, innehåller giltiga values för identiteten column, används dessa values.
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;
Begränsningar för identitet column
Följande begränsningar finns när du arbetar med identitet columns:
- Samtidiga transaktioner stöds inte på tables med identitet columns aktiverad.
- Du kan inte partition en table med en identitet column.
- Du kan inte använda
ALTER TABLE
för attADD
,REPLACE
ellerCHANGE
en identitet column. - Du kan inte update värdet för en identitet column för en befintlig post.
Kommentar
Om du vill ändra IDENTITY
värdet för en befintlig post måste du ta bort posten och INSERT
den som en ny post.