Поделиться через


Генерируемые столбцы 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), а тип colTIMESTAMP.
  • Четыре столбца раздела, определенные YEAR(col), MONTH(col), DAY(col), HOUR(col), и тип colTIMESTAMP.
  • 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).

Чтобы создать новую таблицу со столбцом идентификаторов и заполнить её существующими данными, выполните следующие действия:

  1. Создайте таблицу с правильной схемой, включая определение столбца с идентичностью и другие свойства таблицы.
  2. 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 в качестве новой записи.