Delta Lake-genererade kolumner

Important

Den här funktionen finns som allmänt tillgänglig förhandsversion.

Delta Lake-genererade kolumner beräknar och lagrar automatiskt värden från ett användardefinierat uttryck över andra kolumner i tabellen. När du skriver till en tabell utan att ange värden för genererade kolumner beräknar Delta Lake dem automatiskt. Om du anger värden måste de uppfyllas (<value> <=> <generation expression>) IS TRUE eller så misslyckas skrivning. Se Begränsningar för Azure Databricks.

Du kan till exempel beräkna en price_with_tax kolumn från base_price * 1.1 utan att behöva skriva för att ange data för price_with_tax.

Precis som vanliga kolumner lagras genererade kolumner fysiskt i tabellens underliggande datafiler.

Note

När genererade kolumner aktiveras uppgraderas tabellskrivarens protokoll. Detta kan påverka kompatibiliteten med externa Delta Lake-klienter. Se Delta Lake-funktionskompatibilitet och protokoll.

Skapa en tabell med genererade kolumner

I följande exempel visas hur du skapar en tabell med genererade kolumner:

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

Uttryck som stöds

Ett generationsuttryck kan använda valfri deterministisk SQL-funktion som alltid returnerar samma resultat för samma indata. Ett exempel:

  • Aritmetik: base_price * 1.1
  • Strängfunktioner: CONCAT(first_name, ' ', last_name), SUBSTRING(col, 1, 3)
  • Datumfunktioner: CAST(birthDate AS DATE), YEAR(eventTime)

Följande funktionstyper stöds inte:

  • Användardefinierade funktioner
  • Aggregatfunktioner
  • Fönsterfunktioner
  • Funktioner som returnerar flera rader

Generering av partitionsfilter

Note

Databricks rekommenderar flytande klustring för alla nya Delta Lake-tabeller. Se Använda flytande klustring för tabeller.

När du partitionerar en tabell med hjälp av en genererad kolumn och fråga i baskolumnen härleder Delta Lake automatiskt partitionsfilter om möjligt. Du behöver inte filtrera den genererade partitionskolumnen explicit. Delta Lake härleder partitionsintervallet från baskolumnvärdet.

Photon krävs i Databricks Runtime 10.4 LTS och nedan. Photon krävs inte i Databricks Runtime 11.3 LTS och senare.

Generering av partitionsfilter stöds för följande uttryck:

  • CAST(col AS DATE) och typen av col är TIMESTAMP.
  • YEAR(col) och typen av col är TIMESTAMP.
  • Två partitionskolumner som definieras av YEAR(col), MONTH(col) och typen av col är TIMESTAMP.
  • Tre partitionskolumner som definieras av YEAR(col), MONTH(col), DAY(col) och typen av col är TIMESTAMP.
  • Fyra partitionskolumner som definieras av YEAR(col), MONTH(col), DAY(col), HOUR(col) och typen av col är TIMESTAMP.
  • SUBSTRING(col, pos, len) och typen av col är STRING
  • DATE_FORMAT(col, format) och typen av col är TIMESTAMP.
    • Du kan bara använda datumformat med följande mönster: yyyy-MM och yyyy-MM-dd-HH.
    • I Databricks Runtime 10.4 LTS och senare kan du också använda följande mönster: yyyy-MM-dd.

Exempel: enskild partition

Till exempel med följande tabell:

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

Delta Lake genererar automatiskt ett partitionsfilter så att föregående fråga endast läser data i partitionen date=2020-10-01 även om ett partitionsfilter inte har angetts.

Använd en EXPLAIN sats och kontrollera den angivna planen för att se om Delta Lake automatiskt genererar några partitionsfilter.

Exempel: flera partitioner

Till exempel med följande tabell:

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

Delta Lake genererar automatiskt ett partitionsfilter så att föregående fråga endast läser data i partitionen year=2020/month=10/day=01 även om ett partitionsfilter inte har angetts.

Använd en EXPLAIN sats och kontrollera den angivna planen för att se om Delta Lake automatiskt genererar några partitionsfilter.

Identitetskolumner

Important

Om du deklarerar en identitetskolumn i en Delta Lake-tabell inaktiveras samtidiga transaktioner. Använd endast identitetskolumner i användningsfall där samtidiga skrivningar till måltabellen inte krävs. Se Begränsningar för identitetskolumner.

Delta Lake-identitetskolumner är en typ av genererad kolumn som tilldelar unika värden för varje post som infogas i en tabell. I följande exempel visas den grundläggande syntaxen för att deklarera en identitetskolumn under en create table-instruktion:

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

Scala- och Python-API:er för identitetskolumner är tillgängliga i Databricks Runtime 16.0 och senare.

Om du vill se alla SQL-syntaxalternativ för att skapa tabeller med identitetskolumner kan du läsa 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.

Värden som tilldelas av identitetskolumner är unika och ökar i riktning mot det angivna steget och i multiplar av den angivna stegstorleken, men garanteras inte vara sammanhängande. Till exempel, med ett startvärde på 0 och en stegstorlek på 2, är alla värden positiva jämna tal, men vissa jämna tal kan hoppas över.

När du använder satsen GENERATED BY DEFAULT AS IDENTITYkan infogningsoperationer ange värden för identitetskolumnen. Ändra villkoret till GENERATED ALWAYS AS IDENTITY för att åsidosätta möjligheten att ange värden manuellt.

Identitetskolumner stöder endast BIGINT typ och åtgärder misslyckas om det tilldelade värdet överskrider det intervall som stöds av BIGINT.

Mer information om hur du synkroniserar identitetskolumnvärden med data finns iALTER TABLE ... COLUMN -satsen.

CTAS- och identitetskolumner

Du kan inte definiera schema, begränsningar för identitetskolumner eller andra tabellspecifikationer när du använder en CREATE TABLE table_name AS SELECT-instruktion (CTAS).

Om du vill skapa en ny tabell med en identitetskolumn och fylla den med befintliga data gör du följande:

  1. Skapa en tabell med rätt schema, inklusive identitetskolumndefinitionen och andra tabellegenskaper.
  2. Kör en INSERT åtgärd.

I följande exempel används nyckelordet DEFAULT för att definiera identitetskolumnen. Om data som infogas i tabellen innehåller giltiga värden för identitetskolumnen används dessa värden.

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;

Begränsningar för identitetskolumner

Följande begränsningar finns när du arbetar med identitetskolumner:

  • Samtidiga transaktioner stöds inte i tabeller med identitetskolumner aktiverade.
  • Du kan inte partitionera en tabell efter en identitetskolumn.
  • Du kan inte använda ALTER TABLE till ADD, REPLACEeller CHANGE en identitetskolumn.
  • Du kan inte uppdatera värdet för en identitetskolumn för en befintlig post.

Note

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.

Genererade kolumner och kolumnmasker

En genererad kolumn kan inte referera till en kolumn som har en kolumnmask tillämpad eftersom det genererade värdet skulle avslöja underliggande data som masken skyddar. Detta genererar ett fel och frågan misslyckas. Se Radfilter och kolumnmasker.

Här är exempel på felen:

För att lösa alla dessa fel måste du göra om tabellen så att genererade kolumner och maskerade kolumner inte överlappar varandra.