Генерируемые столбцы Delta Lake
Внимание
Эта функция предоставляется в режиме общедоступной предварительной версии.
Delta Lake поддерживает созданные столбцы, которые являются особым типом столбца, значения которых автоматически создаются на основе указанной пользователем функции над другими столбцами в таблице Delta. При записи в таблицу с генерируемыми столбцами, если вы не предоставляете значения для них явно, Delta Lake автоматически вычисляет эти значения. Например, можно автоматически создать столбец даты (для секционирования таблицы по дате) из столбца метки времени; все записи в таблицу должны указывать только данные для столбца метки времени. Однако если вы явно предоставляете значения для них, значения должны соответствовать ограничению (<value> <=> <generation expression>) IS TRUE
или запись завершится ошибкой.
Внимание
Таблицы, созданные с созданными столбцами, имеют более высокую версию протокола записи таблиц, чем по умолчанию. См. Как Azure Databricks управляет совместимостью функций Delta Lake?, чтобы понять управление версиями протоколов таблиц и то, что означает иметь более высокую версию версии протокола таблицы.
Создание таблицы с созданными столбцами
В следующем примере показано, как создать таблицу с созданными столбцами:
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()
Созданные столбцы хранятся так же, как если бы они были обычными столбцами. То есть, они занимают место в хранилище.
Следующие ограничения применяются к созданным столбцам:
- Выражение поколения может использовать любые функции SQL в Spark, которые всегда возвращают тот же результат при указании одинаковых значений аргументов, за исключением следующих типов функций:
- Определяемые пользователем функции.
- Агрегатные функции.
- Функции окна.
- Функции, возвращающие несколько строк.
Delta Lake может создавать фильтры секций для запроса всякий раз, когда столбец секции определяется одним из следующих выражений:
Примечание.
Фотон требуется в Databricks Runtime 10.4 LTS и ниже. Фотон не требуется в Databricks Runtime 11.3 LTS и более поздних версиях.
-
CAST(col AS DATE)
и типcol
—TIMESTAMP
. -
YEAR(col)
и типcol
—TIMESTAMP
. - Два столбца секции определяются
YEAR(col), MONTH(col)
иcol
, а типcol
— этоTIMESTAMP
. - Три столбца секции, определяемые при помощи
YEAR(col), MONTH(col), DAY(col)
, а типcol
—TIMESTAMP
. - Четыре столбца раздела, определенные
YEAR(col), MONTH(col), DAY(col), HOUR(col)
, и типcol
—TIMESTAMP
. -
SUBSTRING(col, pos, len)
и типcol
—STRING
. -
DATE_FORMAT(col, format)
и типcol
—TIMESTAMP
.- Форматы дат можно использовать только со следующими шаблонами:
yyyy-MM
иyyyy-MM-dd-HH
. - В Databricks Runtime 10.4 LTS и более поздних версиях можно также использовать следующий шаблон:
yyyy-MM-dd
- Форматы дат можно использовать только со следующими шаблонами:
Если столбец секции определяется одним из предыдущих выражений, и запрос фильтрует данные с использованием базового столбца генерационного выражения, Delta Lake анализирует связь между базовым и созданным столбцами и, если возможно, применяет фильтры секций, основанные на созданном столбце секции. Например, учитывая следующую таблицу:
CREATE TABLE events(
eventId BIGINT,
data STRING,
eventType STRING,
eventTime TIMESTAMP,
eventDate date GENERATED ALWAYS AS (CAST(eventTime AS DATE))
)
PARTITIONED BY (eventType, eventDate)
При выполнении следующего запроса:
SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"
Delta Lake автоматически создает фильтр секций, чтобы предыдущий запрос только считывал данные в разделе date=2020-10-01
даже если фильтр секции не указан.
В качестве другого примера, учитывая следующую таблицу:
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)
При выполнении следующего запроса:
SELECT * FROM events
WHERE eventTime >= "2020-10-01 00:00:00" <= "2020-10-01 12:00:00"
Delta Lake автоматически создает фильтр секций, чтобы предыдущий запрос только считывал данные в разделе year=2020/month=10/day=01
даже если фильтр секции не указан.
Вы можете использовать предложение EXPLAIN и проверить предоставленный план, чтобы узнать, создаёт ли Delta Lake автоматически какие-либо фильтры разделов.
Использование столбцов удостоверений в Delta Lake
Внимание
Объявление столбца идентификаторов в таблице Delta отключает выполнение одновременных транзакций. Используйте только идентификационные столбцы в случаях, когда одновременные записи в целевую таблицу не нужны.
Идентификационные столбцы Delta Lake — это тип сгенерированного столбца, который назначает уникальные значения для каждой записи, вставленной в таблицу. В следующем примере показан базовый синтаксис для объявления столбца идентификатора в инструкции создания таблицы.
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()
Примечание.
API Scala и Python для идентичных столбцов доступны в Databricks Runtime 16.0 и выше.
Чтобы просмотреть все параметры синтаксиса SQL для создания таблиц со столбцами идентификаторов, см. CREATE TABLE[USING].
При необходимости можно указать следующее:
- Начальное значение.
- Размер шага, который может быть положительным или отрицательным.
Начальное значение и размер шага по умолчанию 1
. Невозможно указать размер 0
шага.
Значения, назначенные identity-столбцами, являются уникальными и увеличиваются соответственно указанному шагу, и в кратных значениях указанного шага, но их непрерывность не гарантируется. Например, с начальным значением 0
и размером шага 2
все значения - положительные четные числа, но некоторые числа могут быть пропущены.
При использовании предложения GENERATED BY DEFAULT AS IDENTITY
операции вставки могут указывать значения для столбца идентичности. Измените условие на GENERATED ALWAYS AS IDENTITY
, чтобы переопределить возможность вручную задавать значения.
Колонки идентификаторов поддерживают только тип BIGINT
, а операции завершаются ошибкой, если назначенное значение превышает диапазон, поддерживаемый BIGINT
.
Сведения о синхронизации значений столбцов удостоверений с данными см. в ALTER TABLE ...COLUMN предложении.
Столбцы CTAS и столбцы идентификаторов
Невозможно определить схему, ограничения столбца с идентификатором или другие параметры таблицы при использовании оператора CREATE TABLE table_name AS SELECT
(CTAS).
Чтобы создать новую таблицу со столбцом идентификаторов и заполнить её существующими данными, выполните следующие действия:
- Создайте таблицу с правильной схемой, включая определение столбца с идентичностью и другие свойства таблицы.
-
INSERT
Выполните операцию.
В следующем примере для определения столбца идентификаторов используется ключевое слово DEFAULT
. Если данные, вставляемые в таблицу, содержат допустимые значения для столбца идентификаторов, эти значения используются.
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;
Ограничения столбцов удостоверений
При работе с идентификационными столбцами существуют следующие ограничения:
- Одновременные транзакции не поддерживаются в таблицах с включенными идентификационными столбцами.
- Вы не можете секционировать таблицу по столбцу идентификаторов.
- Нельзя использовать
ALTER TABLE
дляADD
,REPLACE
илиCHANGE
столбца удостоверения. - Нельзя обновить значение столбца идентификатора для существующей записи.
Примечание.
Чтобы изменить IDENTITY
значение существующей записи, необходимо удалить запись и INSERT
в качестве новой записи.