Door Delta Lake gegenereerde kolommen

Important

Deze functie bevindt zich in openbare preview-versie.

Door Delta Lake gegenereerde kolommen berekenen automatisch waarden en slaan deze op op basis van een door de gebruiker gedefinieerde expressie over andere kolommen in de tabel. Wanneer u naar een tabel schrijft zonder waarden voor gegenereerde kolommen op te geven, worden deze automatisch berekend door Delta Lake. Als u wel waarden opgeeft, moeten ze voldoen aan (<value> <=> <generation expression>) IS TRUE of mislukt de schrijfbewerking. Zie Beperkingen voor Azure Databricks.

U kunt bijvoorbeeld een price_with_tax-kolom berekenen op basis van base_price * 1.1 zonder dat schrijfbewerkingen gegevens voor price_with_tax hoeven op te geven.

Net als bij gewone kolommen worden gegenereerde kolommen fysiek opgeslagen in de onderliggende gegevensbestanden van de tabel.

Note

Door gegenereerde kolommen in te schakelen, wordt het tabelschrijverprotocol bijgewerkt. Dit kan van invloed zijn op de compatibiliteit met externe Delta Lake-clients. Bekijk de compatibiliteit en protocollen van Delta Lake-functies.

Een tabel maken met gegenereerde kolommen

In het volgende voorbeeld ziet u hoe u een tabel maakt met gegenereerde kolommen:

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

Ondersteunde expressies

Een generatieexpressie kan elke deterministische SQL-functie gebruiken die altijd hetzelfde resultaat retourneert voor dezelfde invoer. Voorbeeld:

  • Rekenkunde: base_price * 1.1
  • Stringfuncties: CONCAT(first_name, ' ', last_name), SUBSTRING(col, 1, 3)
  • Datumfuncties: CAST(birthDate AS DATE), YEAR(eventTime)

De volgende functietypen worden niet ondersteund:

  • Door de gebruiker gedefinieerde functies
  • Gecompileerde functies
  • Vensterfuncties
  • Functies die meerdere rijen retourneren

Partitiefilter genereren

Note

Databricks raadt vloeibare clustering aan voor alle nieuwe Delta Lake-tabellen. Zie Liquid Clustering gebruiken voor tabellen.

Wanneer u een tabel partitioneert met behulp van een gegenereerde kolom en query op de basiskolom, leidt Delta Lake indien mogelijk partitiefilters automatisch af. U hoeft niet expliciet te filteren op de gegenereerde partitiekolom. Delta Lake leidt het partitiebereik af uit de waarde van de basiskolom.

Photon is vereist in Databricks Runtime 10.4 LTS en hieronder. Photon is niet vereist in Databricks Runtime 11.3 LTS en hoger.

Het genereren van partitiefilters wordt ondersteund voor de volgende expressies:

  • CAST(col AS DATE) en het type col is TIMESTAMP.
  • YEAR(col) en het type col is TIMESTAMP.
  • Twee partitiekolommen gedefinieerd door YEAR(col), MONTH(col) en het type col is TIMESTAMP.
  • Drie partitiekolommen gedefinieerd door YEAR(col), MONTH(col), DAY(col) en het type col is TIMESTAMP.
  • Vier partitiekolommen gedefinieerd door YEAR(col), MONTH(col), DAY(col), HOUR(col) en het type col is TIMESTAMP.
  • SUBSTRING(col, pos, len) en het type col is STRING
  • DATE_FORMAT(col, format) en het type col is TIMESTAMP.
    • U kunt alleen datumnotaties met de volgende patronen gebruiken: yyyy-MM en yyyy-MM-dd-HH.
    • In Databricks Runtime 10.4 LTS en hoger kunt u ook het volgende patroon gebruiken: yyyy-MM-dd

Voorbeeld: één partitie

Bijvoorbeeld, op basis van de volgende tabel:

CREATE TABLE events(
eventId BIGINT,
data STRING,
eventType STRING,
eventTime TIMESTAMP,
eventDate date GENERATED ALWAYS AS (CAST(eventTime AS DATE))
)
PARTITIONED BY (eventType, eventDate)

Als u vervolgens de volgende query uitvoert:

SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" AND eventTime <= "2020-10-01 12:00:00"

Delta Lake genereert automatisch een partitiefilter, zodat de voorgaande query alleen de gegevens in de partitie date=2020-10-01 leest, zelfs als er geen partitiefilter is opgegeven.

Gebruik een EXPLAIN component en controleer het opgegeven plan om te zien of Delta Lake automatisch partitiefilters genereert.

Voorbeeld: meerdere partities

Bijvoorbeeld, op basis van de volgende tabel:

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)

Als u vervolgens de volgende query uitvoert:

SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" AND eventTime <= "2020-10-01 12:00:00"

Delta Lake genereert automatisch een partitiefilter, zodat de voorgaande query alleen de gegevens in de partitie year=2020/month=10/day=01 leest, zelfs als er geen partitiefilter is opgegeven.

Gebruik een EXPLAIN component en controleer het opgegeven plan om te zien of Delta Lake automatisch partitiefilters genereert.

Identiteitskolommen

Important

Het definiëren van een identiteitskolom in een Delta Lake-tabel schakelt gelijktijdige transacties uit. Gebruik alleen identiteitskolommen in gebruiksvoorbeelden waarbij gelijktijdige schrijfbewerkingen naar de doeltabel niet vereist zijn. Zie Beperkingen voor identiteitskolommen.

Delta Lake-identiteitskolommen zijn een type gegenereerde kolom waarmee unieke waarden worden toegewezen voor elke record die in een tabel is ingevoegd. In het volgende voorbeeld ziet u de basissyntaxis voor het definiëren van een identity-kolom tijdens een CREATE TABLE-instructie.

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- en Python-API's voor identiteitskolommen zijn beschikbaar in Databricks Runtime 16.0 en hoger.

Zie CREATE TABLE [USING]voor alle OPTIES voor SQL-syntaxis voor het maken van tabellen met identiteitskolommen.

U kunt desgewenst het volgende opgeven:

  • Een beginwaarde.
  • Een stapgrootte, die positief of negatief kan zijn.

Zowel de beginwaarde als de stapgrootte is standaard ingesteld op 1. U kunt geen stapgrootte opgeven van 0.

Waarden die zijn toegewezen door identiteitskolommen zijn uniek en stijgen volgens de opgegeven stap en in veelvouden van de opgegeven stapgrootte, maar er is geen garantie dat ze aaneengesloten zijn. Bijvoorbeeld, met een beginwaarde van 0 en een stapgrootte van 2, zijn alle waarden positieve even getallen, maar sommige even getallen kunnen worden overgeslagen.

Wanneer u de component GENERATED BY DEFAULT AS IDENTITYgebruikt, kunnen invoegbewerkingen waarden opgeven voor de identiteitskolom. Wijzig de component zodat GENERATED ALWAYS AS IDENTITY deze de mogelijkheid om handmatig waarden in te stellen overschrijft.

Identiteitskolommen ondersteunen alleen het BIGINT type en bewerkingen mislukken als de toegewezen waarde het bereik overschrijdt dat wordt ondersteund door BIGINT.

Zie ALTER TABLE de clause ... COLUMN voor meer informatie over het synchroniseren van waarden voor identiteitskolommen met gegevens.

CTAS en identiteitskolommen

U kunt geen beperkingen voor schema's, identiteitskolommen of andere tabelspecificaties definiëren wanneer u een CREATE TABLE table_name AS SELECT CTAS-instructie (CTAS) gebruikt.

Ga als volgt te werk om een nieuwe tabel te maken met een identiteitskolom en deze te vullen met bestaande gegevens:

  1. Maak een tabel met het juiste schema, inclusief de definitie van de identiteitskolom en andere tabeleigenschappen.
  2. Voer een INSERT bewerking uit.

In het volgende voorbeeld wordt het DEFAULT trefwoord gebruikt om de identiteitskolom te definiëren. Als gegevens die in de tabel worden ingevoegd geldige waarden voor de identiteitskolom bevatten, worden deze waarden gebruikt.

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;

Beperkingen voor identiteitskolommen

De volgende beperkingen gelden voor het werken met identiteitskolommen:

  • Gelijktijdige transacties worden niet ondersteund voor tabellen waarvoor identiteitskolommen zijn ingeschakeld.
  • U kunt een tabel niet partitioneren op basis van een identiteitskolom.
  • U kunt niet gebruiken ALTER TABLE voor ADD, REPLACEof CHANGE een identiteitskolom.
  • U kunt de waarde van een identiteitskolom voor een bestaande record niet bijwerken.

Note

Als u de IDENTITY waarde voor een bestaande record wilt wijzigen, moet u de record en INSERT deze als een nieuwe record verwijderen.

Gegenereerde kolommen en kolommaskers

Een gegenereerde kolom kan niet verwijzen naar een kolom waarop een kolommasker is toegepast omdat met de gegenereerde waarde de onderliggende gegevens worden weergegeven die door het masker worden beveiligd. Hiermee wordt een fout gegenereerd en mislukt de query. Zie rijfilters en kolommaskers.

Hier volgen enkele voorbeelden van de fouten:

Als u al deze fouten wilt oplossen, moet u de tabel opnieuw ontwerpen, zodat gegenereerde kolommen en gemaskeerde kolommen elkaar niet overlappen.