Door Delta Lake gegenereerde kolommen
Belangrijk
Deze functie is beschikbaar als openbare preview.
Delta Lake ondersteunt gegenereerde kolommen die een speciaal type kolom zijn waarvan de waarden automatisch worden gegenereerd op basis van een door de gebruiker opgegeven functie voor andere kolommen in de Delta-tabel. Wanneer u naar een tabel schrijft met gegenereerde kolommen en u er niet expliciet waarden voor opgeeft, worden de waarden automatisch berekend door Delta Lake. U kunt bijvoorbeeld automatisch een datumkolom genereren (voor het partitioneren van de tabel op datum) uit de tijdstempelkolom; schrijfbewerkingen in de tabel hoeven alleen de gegevens voor de tijdstempelkolom op te geven. Als u echter expliciet waarden voor deze waarden opgeeft, moeten de waarden voldoen aan de beperking (<value> <=> <generation expression>) IS TRUE
of mislukt de schrijfbewerking met een fout.
Belangrijk
Tabellen die zijn gemaakt met gegenereerde kolommen hebben een hogere protocolversie voor table writer dan de standaardversie. Zie Hoe beheert Azure Databricks de compatibiliteit van Delta Lake-functies? Om inzicht te krijgen in versiebeheer van tabellen en wat het betekent dat u een hogere versie van een tabelprotocolversie hebt.
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()
Gegenereerde kolommen worden opgeslagen alsof het normale kolommen zijn. Dat wil gezegd, ze bezetten opslag.
De volgende beperkingen gelden voor gegenereerde kolommen:
- Een generatieexpressie kan gebruikmaken van SQL-functies in Spark die altijd hetzelfde resultaat retourneren wanneer dezelfde argumentwaarden worden gegeven, met uitzondering van de volgende typen functies:
- Door de gebruiker gedefinieerde functies.
- Statistische functies.
- Vensterfuncties.
- Functies retourneren meerdere rijen.
Delta Lake kan partitiefilters voor een query genereren wanneer een partitiekolom wordt gedefinieerd door een van de volgende expressies:
Notitie
Photon is vereist in Databricks Runtime 10.4 LTS en hieronder. Photon is niet vereist in Databricks Runtime 11.3 LTS en hoger.
CAST(col AS DATE)
en het typecol
isTIMESTAMP
.YEAR(col)
en het typecol
isTIMESTAMP
.- Twee partitiekolommen gedefinieerd door
YEAR(col), MONTH(col)
en het typecol
isTIMESTAMP
. - Drie partitiekolommen gedefinieerd door
YEAR(col), MONTH(col), DAY(col)
en het typecol
isTIMESTAMP
. - Vier partitiekolommen gedefinieerd door
YEAR(col), MONTH(col), DAY(col), HOUR(col)
en het typecol
isTIMESTAMP
. SUBSTRING(col, pos, len)
en het typecol
isSTRING
DATE_FORMAT(col, format)
en het typecol
isTIMESTAMP
.- U kunt alleen datumnotaties met de volgende patronen gebruiken:
yyyy-MM
enyyyy-MM-dd-HH
. - In Databricks Runtime 10.4 LTS en hoger kunt u ook het volgende patroon gebruiken:
yyyy-MM-dd
- U kunt alleen datumnotaties met de volgende patronen gebruiken:
Als een partitiekolom wordt gedefinieerd door een van de voorgaande expressies en een query gegevens filtert met behulp van de onderliggende basiskolom van een generatie-expressie, kijkt Delta Lake naar de relatie tussen de basiskolom en de gegenereerde kolom en vult indien mogelijk partitiefilters op basis van de gegenereerde partitiekolom. 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" <= "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.
Een ander voorbeeld, gezien 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" <= "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.
U kunt een EXPLAIN-component gebruiken en het opgegeven plan controleren om te zien of Delta Lake automatisch partitiefilters genereert.
Identiteitskolommen gebruiken in Delta Lake
Belangrijk
Als u een identiteitskolom in een Delta-tabel declareren, worden gelijktijdige transacties uitgeschakeld. Gebruik alleen identiteitskolommen in gebruiksvoorbeelden waarbij gelijktijdige schrijfbewerkingen naar de doeltabel niet vereist zijn.
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 declareren van een identiteitskolom tijdens een instructie tabel maken:
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()
Notitie
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 verhogen in de richting van de opgegeven stap, en in veelvouden van de opgegeven stapgrootte, maar zijn niet gegarandeerd aaneengesloten. 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 IDENTITY
gebruikt, 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
.
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:
- Maak een tabel met het juiste schema, inclusief de definitie van de identiteitskolom en andere tabeleigenschappen.
- 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
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;
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 deze niet gebruiken
ALTER TABLE
voorADD
,REPLACE
ofCHANGE
een identiteitskolom. - U kunt de waarde van een identiteitskolom voor een bestaande record niet bijwerken.
Notitie
Als u de IDENTITY
waarde voor een bestaande record wilt wijzigen, moet u de record en INSERT
deze als een nieuwe record verwijderen.