Columnas generadas por Delta Lake

Importante

Esta característica está en versión preliminar pública.

Delta Lake ahora admite columnas generadas, que son un tipo especial de columna cuyos valores se generan automáticamente según una función especificada por el usuario sobre otras columnas de la tabla Delta. Cuando escribe en una tabla con columnas generadas y no proporciona valores de forma explícita para ellas, Delta Lake calcula automáticamente los valores. Por ejemplo, puede generar automáticamente una columna de fecha (para crear particiones de la tabla por fecha) a partir de la columna de marca de tiempo; cualquier escritura en la tabla solo deberá especificar los datos de la columna de marca de tiempo. Sin embargo, si proporciona explícitamente valores para ellas, los valores deben satisfacer la restricción (<value> <=> <generation expression>) IS TRUE o la escritura producirá un error.

Importante

Las tablas creadas con columnas generadas tienen una versión del protocolo de escritor de tablas superior a la predeterminada. Consulte ¿Cómo administra Azure Databricks la compatibilidad de funciones de Delta Lake? para comprender el versionado de protocolos de tabla y lo que significa tener una versión superior de una versión de protocolo de tabla.

Creación de una tabla con columnas generadas

En el ejemplo siguiente se muestra cómo crear una tabla con columnas generadas:

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

Las columnas generadas se almacenan como si fueran columnas normales. Es decir, ocupan almacenamiento.

Las restricciones siguientes se aplican a las columnas generadas:

  • Una expresión de generación puede usar cualquier función de SQL en Spark que devuelva siempre el mismo resultado cuando se den los mismos valores de argumento, excepto los siguientes tipos de funciones:
    • Funciones definidas por el usuario.
    • Funciones de agregado.
    • Funciones de ventana.
    • Funciones que devuelven varias filas.

Delta Lake puede generar filtros de partición para una consulta cada vez que una columna de partición se define mediante una de las siguientes expresiones:

Nota:

Photon es necesario en Databricks Runtime 10.4 LTS y versiones anteriores. Photon no es necesario en Databricks Runtime 11.3 LTS y versiones posteriores.

  • CAST(col AS DATE) y el tipo de col es TIMESTAMP.
  • YEAR(col) y el tipo de col es TIMESTAMP.
  • Dos columnas de partición definidas por YEAR(col), MONTH(col) y el tipo de col es TIMESTAMP.
  • Tres columnas de partición definidas por YEAR(col), MONTH(col), DAY(col) y el tipo de col es TIMESTAMP.
  • Cuatro columnas de partición definidas por YEAR(col), MONTH(col), DAY(col), HOUR(col) y el tipo de col es TIMESTAMP.
  • SUBSTRING(col, pos, len) y el tipo de col es STRING
  • DATE_FORMAT(col, format) y el tipo de col es TIMESTAMP.
    • Solo puede utilizar formatos de fecha con los siguientes patrones: yyyy-MM y yyyy-MM-dd-HH.
    • En Databricks Runtime 10.4 LTS y posteriores, también puede utilizar el siguiente patrón: yyyy-MM-dd.

Si una de las expresiones anteriores define una columna de la partición y una consulta filtra los datos mediante la columna base subyacente de una expresión de generación, Delta Lake examina la relación entre la columna base y la columna generada y rellena los filtros de partición en función de los datos de la columna de partición generada, siempre que sea posible. Por ejemplo, si tenemos la siguiente tabla:

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

Si después se ejecuta la siguiente consulta:

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

Delta Lake genera automáticamente un filtro de partición para que la consulta anterior solo lea los datos de la partición date=2020-10-01, incluso si no se especifica ningún filtro de partición.

En este otro ejemplo, tenemos la siguiente tabla:

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)

Si después se ejecuta la siguiente consulta:

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

Delta Lake genera automáticamente un filtro de partición para que la consulta anterior solo lea los datos de la partición year=2020/month=10/day=01, aunque no se especifique ningún filtro de partición.

Puede usar una cláusula EXPLAIN y comprobar el plan proporcionado para ver si Delta Lake genera automáticamente filtros de partición.

Uso de columnas de identidad en Delta Lake

Importante

Declarar una columna de identidad en una tabla Delta deshabilita las transacciones concurrentes. Utilice columnas de identidad únicamente en casos en los que no se requieran escrituras simultáneas en la tabla de destino.

Las columnas de identidad de Delta Lake son un tipo de columna generada que asigna valores únicos para cada registro insertado en una tabla. En el siguiente ejemplo se muestra la sintaxis básica para declarar una columna de identidad durante una instrucción de creación de una tabla:

CREATE TABLE table_name (
  identity_col BIGINT GENERATED BY DEFAULT AS IDENTITY,
  other_column ...)

Para ver todas las opciones de sintaxis para la creación de tablas con columnas de identidad, consulte CREAR TABLAS [USING].

Opcionalmente, puede especificar lo siguiente:

  • Un valor inicial.
  • Un tamaño de paso, que puede ser positivo o negativo.

Los valores asignados por las columnas de identidad son únicos y se incrementan en la dirección del paso especificado, y en múltiplos del tamaño del paso especificado, pero no se garantiza que sean contiguos. Por ejemplo, con un valor inicial de 0 y un tamaño de paso de 2, todos los valores son números pares positivos, pero es posible que se omitan algunos números pares.

Al usar la cláusula GENERATED BY DEFAULT AS IDENTITY, las operaciones de inserción pueden especificar valores para la columna de identidad. Modifique la cláusula para que sea GENERATED ALWAYS AS IDENTITY para invalidar la capacidad de establecer manualmente los valores.

Las columnas de identidad solo admiten el tipo BIGINT, y las operaciones se cancelan si el valor asignado excede el rango admitido por BIGINT.

Para más información sobre la sincronización de valores de columnas de identidad con datos, consulte TABLA ALTERNATIVA.

Limitaciones de columna de identidad

Existen las siguientes limitaciones al trabajar con columnas de identidad:

  • Las tablas con columnas de identidad habilitadas no permiten transacciones simultáneas.
  • No se puede particionar una tabla por una columna de identidad.
  • No se puede usar ALTER TABLE para ADD, REPLACE o CHANGE una columna de identidad.
  • No se puede actualizar el valor de una columna de identidad para un registro existente.

Nota:

Para cambiar el valor de IDENTITY para un registro existente, debe eliminar el registro y INSERT como un nuevo registro.