Delta Lake colunas geradas

Visualização

Este recurso está em visualização pública.

O Delta Lake oferece suporte a colunas geradas, que são um tipo especial de coluna cujos valores são gerados automaticamente com base em uma função especificada pelo usuário sobre outras colunas na tabela Delta. Quando você grava em uma tabela com colunas geradas e não fornece valores explicitamente para elas, o Delta Lake compute automaticamente os valores. Por exemplo, você pode gerar automaticamente uma coluna de data (para particionar a tabela por data) a partir da coluna de carimbo de data/hora; qualquer gravação na tabela precisa apenas especificar os dados para a coluna de carimbo de data/hora. No entanto, se você fornecer valores explicitamente para eles, os valores deverão atender à restrição (<value> <=> <generation expression>) IS TRUE ou a gravação falhará com um erro.

Importante

Tabelas criadas com colunas geradas possuem uma versão de protocolo de gravador de tabela superior ao default. Consulte Como o Databricks gerencia a compatibilidade de recursos do Delta Lake? para entender o versionamento de protocolo de tabela e o que significa ter uma versão superior de uma versão de protocolo de tabela.

Criar uma tabela com colunas geradas

O exemplo a seguir mostra como criar uma tabela com colunas geradas:

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

As colunas geradas são armazenadas como se fossem colunas normais. Ou seja, eles ocupam armazenamento.

As seguintes restrições se aplicam às colunas geradas:

  • Uma expressão de geração pode usar quaisquer funções SQL no Spark que sempre retornam o mesmo resultado quando recebem os mesmos valores de argumento, exceto os seguintes tipos de funções:

    • Funções definidas pelo usuário.

    • Funções agregadas.

    • Funções da janela.

    • Funções que retornam várias linhas.

Delta Lake pode gerar filtros de partição para uma query sempre que uma coluna de partição for definida por uma das seguintes expressões:

Observação

O Photon é necessário no Databricks Runtime 10.4 LTS e abaixo. Photon não é necessário em Databricks Runtime 11.3 LTS e acima.

  • CAST(col AS DATE) e o tipo de col é TIMESTAMP.

  • YEAR(col) e o tipo de col é TIMESTAMP.

  • Duas colunas de partição definidas por YEAR(col), MONTH(col) e o tipo de col é TIMESTAMP.

  • Três colunas de partição definidas por YEAR(col), MONTH(col), DAY(col) e o tipo de col é TIMESTAMP.

  • Quatro colunas de partição definidas por YEAR(col), MONTH(col), DAY(col), HOUR(col) e o tipo de col é TIMESTAMP.

  • SUBSTRING(col, pos, len) e o tipo de col é STRING

  • DATE_FORMAT(col, format) e o tipo de col é TIMESTAMP.

    • Você só pode usar formatos de data com os seguintes padrões: yyyy-MM e yyyy-MM-dd-HH.

    • No Databricks Runtime 10.4 LTSe acima, você também pode usar o seguinte padrão: yyyy-MM-dd.

Se uma coluna de partição for definida por uma das expressões anteriores e uma query filtrar o uso de dados da coluna base subjacente de uma expressão de geração, o Delta Lake examinará a relação entre a coluna base e a coluna gerada e preencherá os filtros de partição com base em a coluna de partição gerada, se possível. Por exemplo, dada a seguinte tabela:

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

Se você executar a seguinte query:

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

O Delta Lake gera automaticamente um filtro de partição para que a query anterior leia apenas os dados na partição date=2020-10-01, mesmo que um filtro de partição não seja especificado.

Como outro exemplo, dada a seguinte tabela:

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)

Se você executar a seguinte query:

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

O Delta Lake gera automaticamente um filtro de partição para que a query anterior leia apenas os dados na partição year=2020/month=10/day=01, mesmo que um filtro de partição não seja especificado.

Você pode usar uma cláusula EXPLAIN e verificar o plano fornecido para ver se o Delta Lake gera automaticamente algum filtro de partição.

Usar colunas de identidade no Delta Lake

Importante

Declarar uma coluna de identidade em uma tabela Delta desabilita as transações concorrentes. Use colunas de identidade apenas em casos de uso em que gravações concorrentes na tabela de destino não são necessárias.

As colunas de identidade Delta Lake são um tipo de coluna gerada que atribui valores exclusivos para cada registro inserido em uma tabela. O exemplo a seguir mostra a sintaxe básica para declarar uma coluna de identidade durante um comando create table:

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

Para ver todas as opções de sintaxe para a criação de tabelas com colunas de identidade, consulte CREATE TABLE [USING].

Opcionalmente, o senhor pode especificar o seguinte:

  • Um valor inicial.

  • A o tamanho do passo, que pode ser positivo ou negativo.

Os valores atribuídos pelas colunas de identidade são exclusivos e incrementados na direção do passo especificado e em múltiplos do tamanho do passo especificado, mas não há garantia de que sejam contíguos. Por exemplo, com um valor inicial de 0 e um tamanho de passo de 2, todos os valores são números pares positivos, mas alguns números pares podem ser ignorados.

Ao usar a cláusula GENERATED BY DEFAULT AS IDENTITY, as operações de inserção podem especificar valores para a coluna de identidade. Modifique a cláusula para GENERATED ALWAYS AS IDENTITY para substituir a capacidade de definir valores manualmente.

As colunas de identidade suportam apenas o tipo BIGINT e as operações falham se o valor atribuído exceder o intervalo suportado por BIGINT.

Para saber como sincronizar valores de coluna de identidade com dados, consulte ALTER TABLE.

Limitações da coluna de identidade

Existem as seguintes limitações ao trabalhar com colunas de identidade:

  • As transações concorrente não são suportadas em tabelas com colunas de identidade ativadas.

  • O senhor não pode particionar uma tabela por uma coluna de identidade.

  • O senhor não pode usar ALTER TABLE para ADD, REPLACE ou CHANGE como coluna de identidade.

  • Não é possível atualizar o valor de uma coluna de identidade para um registro existente.

Observação

Para alterar o valor IDENTITY de um registro existente, o senhor deve excluir o registro e INSERT transformá-lo em um novo registro.