Todos os produtos
Search
Central de documentação

Realtime Compute for Apache Flink:Criar e usar tabelas materializadas

Última atualização: Jun 27, 2026

Este tópico explica como criar uma tabela materializada, executar o backfill de dados, modificar a atualização dos dados e visualizar a linhagem de dados.

Limitações

  • Este recurso está disponível apenas no Ververica Runtime (VVR) 8.0.10 e versões posteriores.

  • Crie tabelas materializadas apenas em um catálogo Apache Paimon que utilize Filesystem ou DLF para armazenamento de metadados. O sistema não suporta catálogos Apache Paimon personalizados.

  • Você deve ter permissões para desenvolver e implantar jobs. Para mais informações, consulte Autorização do console de desenvolvimento.

  • O sistema não suporta objetos temporários, como tabelas temporárias, funções definidas pelo usuário temporárias e views temporárias.

Criar uma tabela materializada

Sintaxe

CREATE MATERIALIZED TABLE [catalog_name.][db_name.]table_name
-- Primary key constraint
[([CONSTRAINT constraint_name] PRIMARY KEY (column_name, ...) NOT ENFORCED)]

[COMMENT table_comment]
-- Partition key
[PARTITIONED BY (partition_column_name1, partition_column_name2, ...)]
-- With options
[WITH (key1=val1, key2=val2, ...)]
-- Data freshness
FRESHNESS = INTERVAL '<num>' { SECOND | MINUTE | HOUR | DAY }
-- Refresh mode
[REFRESH_MODE = { CONTINUOUS | FULL }]
AS  <select_statement>

Parâmetros

Parâmetro

Obrigatório

Descrição

FRESHNESS

Sim

Defina a atualização dos dados da tabela materializada e estabelece a latência máxima permitida para atualizações provenientes das tabelas de origem.

Nota
  • Se uma tabela upstream também for uma tabela materializada, a atualização dos dados da tabela downstream deve ser um múltiplo inteiro positivo da atualização da tabela upstream.

  • A atualização máxima dos dados é de um dia.

AS <select_statement>

Sim

Defina a consulta que popula a tabela materializada. A tabela upstream pode ser uma tabela materializada, uma tabela comum ou uma view. A instrução SELECT suporta todas as consultas Flink SQL.

PRIMARY KEY

Não

Colunas opcionais que identificam exclusivamente cada linha na tabela. Estas colunas não podem conter valores nulos.

PARTITIONED BY

Não

Colunas opcionais usadas para particionar a tabela materializada.

WITH Options

Não

Defina propriedades da tabela e parâmetros de formato de hora para colunas de particionamento.

Por exemplo, defina o parâmetro de formato de hora para uma coluna de particionamento com WITH ('partition.fields.#.date-formatter' = 'yyyyMMdd'). Para mais informações sobre o uso de parâmetros, consulte os exemplos no procedimento.

REFRESH_MODE

Não

Especifica o modo de atualização da tabela materializada. Um modo especificado tem precedência sobre o modo inferido automaticamente pelo framework com base na atualização dos dados. Isso permite lidar com cenários específicos.

  • CONTINUOUS: Um job de streaming atualiza a tabela materializada incrementalmente. Os dados downstream tornam-se visíveis imediatamente ou após a conclusão de um checkpoint.

  • FULL: Um workflow aciona periodicamente atualizações em lote para a tabela materializada. Neste modo, o mecanismo determina automaticamente se deve executar uma atualização completa ou incremental. Para mais informações, consulte Atualizações incrementais para uma tabela materializada. O ciclo de atualização dos dados corresponde à configuração de atualização. Por padrão, os dados são sobrescritos no nível da tabela. Se existirem colunas de particionamento, escolha atualizar apenas a partição mais recente ou todas as partições.

Procedimento

  1. Acesse o console do Realtime Compute for Apache Flink.

  2. Na coluna Actions do workspace desejado, clique em Console.

  3. No painel de navegação à esquerda, clique em Catalogs e, em seguida, clique no catálogo Apache Paimon desejado.

  4. Clique no banco de dados desejado e, em seguida, clique em Create Materialized Table.

    Suponha que você tenha uma tabela de origem chamada orders com uma chave primária order_id, um nome de categoria order_name e um campo de data ds. Os exemplos a seguir mostram como criar tabelas materializadas com base nesta tabela:

    • Crie uma tabela materializada mt_order baseada na tabela orders. A consulta seleciona todas as colunas e a atualização dos dados é definida como 5 segundos.

      CREATE MATERIALIZED TABLE mt_order
      FRESHNESS = INTERVAL '5' SECOND
      AS
      SELECT * FROM `paimon`.`db`.`orders`
      ;
    • Crie uma tabela materializada mt_id baseada na tabela materializada mt_order. A consulta seleciona order_id e ds como colunas da tabela, define order_id como chave primária, ds como coluna de particionamento e a atualização dos dados como 30 minutos.

      CREATE MATERIALIZED TABLE mt_id (
       PRIMARY KEY (order_id) NOT ENFORCED
      )
      PARTITIONED BY(ds)
      FRESHNESS = INTERVAL '30' MINUTE
      AS
      SELECT order_id,ds FROM mt_order
      ;
    • Crie a tabela materializada mt_ds baseada na tabela materializada mt_order e especifique um date-formatter (formato de hora) para a coluna de particionamento ds. A cada execução do agendamento, o horário do agendamento menos a atualização é convertido no valor correspondente da partição ds. Por exemplo, se a atualização dos dados for definida como 1 hora e o horário do agendamento for 2024-01-01 00:00:00, o valor calculado de ds será 20231231, e apenas os dados na partição ds = '20231231' serão atualizados. Se o horário agendado for 2024-01-01 01:00:00, o valor calculado de ds será 20240101, e os dados na partição ds = '20240101' serão atualizados.

      CREATE MATERIALIZED TABLE mt_ds
      PARTITIONED BY(ds)
      WITH (
          'partition.fields.ds.date-formatter' = 'yyyyMMdd'
      )
      FRESHNESS = INTERVAL '1' HOUR
      AS
      SELECT order_id,order_name,ds FROM mt_order
      ;
      Nota
      • Em partition.fields.#.date-formatter, o espaço reservado # deve ser uma coluna de particionamento válida do tipo STRING.

      • A opção partition.fields.#.date-formatter especifica o formato de partição de tempo para a tabela materializada. O espaço reservado # representa o nome de uma coluna de particionamento do tipo string. Essa informação permite que o sistema identifique qual partição atualizar durante uma atualização agendada.

  5. Inicie ou pare a atualização da tabela materializada.

    1. Clique na tabela materializada desejada dentro de seu catálogo.

    2. No canto superior direito, clique em Start Update ou Stop Update.

      Nota

      Se você parar uma atualização em andamento, o job concluirá o ciclo de atualização atual antes de parar.

  6. Visualize os detalhes do job da tabela materializada.

    Na aba Table Schema, na seção Basic Information, clique em Latest Job ou Workflow para visualizar os detalhes.

Modificar uma consulta de tabela materializada

Limitações

  • Modifique a consulta apenas para tabelas materializadas criadas no VVR 11.1 ou posterior.

  • Ao modificar uma consulta, adicione apenas colunas e modifique a lógica de computação. Não altere a ordem das colunas existentes nem modifique suas definições.

    Operação

    Suportado

    Descrição

    Adicionar uma nova coluna

    Sim

    Anexe novas colunas ao schema mantendo a ordem existente das colunas.

    Modificar a lógica de computação de uma coluna existente (sem alterar seu nome ou tipo)

    Sim

    Modifique a lógica de computação, mas mantenha o nome da coluna e o tipo de dados inalterados.

    Alterar a ordem das colunas existentes

    Não

    A ordem das colunas é fixa. Para alterá-la, exclua e recrie a tabela materializada.

    Modificar o nome ou o tipo de dados de uma coluna existente

    Não

    Exclua e recrie a tabela materializada.

Exemplo

  1. Clique em Edit Table e modifique a consulta. O código a seguir fornece um exemplo:

    ALTER MATERIALIZED TABLE `paimon`.`default`.`mt-orders`
        AS
        SELECT
          *,
          price * quantity AS total_price
        FROM orders
        WHERE price * quantity > 1000
    ;
  2. Clique em Preview para ver uma comparação antes e depois.

    image

  3. Clique em OK. Visualize a coluna recém-adicionada e a lógica de consulta modificada na aba Table Schema.

Importante

Adicionar colunas geralmente não afeta os consumidores downstream. No entanto, se um job downstream depender de análise dinâmica (como SELECT * ou mapeamento automático de campos) ao consumir dados da tabela materializada upstream, o job poderá falhar ou relatar um erro de incompatibilidade de formato de dados. Recomendamos evitar a análise dinâmica, usar listas fixas de colunas e atualizar prontamente o schema da tabela downstream sempre que o schema upstream mudar.

Atualizações incrementais

Limitações

Este recurso está disponível apenas no VVR 8.0.11 e versões posteriores.

Modos de atualização

As tabelas materializadas suportam três modos de atualização: streaming, lote completo e lote incremental.

A configuração de atualização dos dados determina o modo. Uma atualização inferior a 30 minutos ativa o modo de streaming, enquanto 30 minutos ou mais ativam o modo de lote. No modo de lote, o mecanismo decide automaticamente entre uma atualização completa ou incremental. Uma atualização incremental computa apenas os dados que mudaram desde a última atualização e os mescla na tabela materializada. Uma atualização completa computa dados para toda a tabela ou partição e sobrescreve os dados existentes na tabela materializada. No modo de lote, o mecanismo prioriza atualizações incrementais e recorre a uma atualização completa apenas quando uma atualização incremental não for possível.

Condições para atualização incremental

Execute uma atualização incremental apenas se a tabela materializada atender a todas as condições a seguir:

  • O parâmetro partition.fields.#.date-formatter não está configurado na definição da tabela.

  • A tabela de origem não possui uma chave primária definida.

  • A consulta na definição da tabela materializada suporta atualizações incrementais conforme descrito na tabela a seguir:

    Cláusula SQL

    Suporte

    SELECT

    Suportado para seleção de colunas e expressões de funções escalares, incluindo funções definidas pelo usuário. Funções agregadas não são suportadas.

    FROM

    Suportado para nomes de tabelas e subconsultas.

    WITH

    Suportado para Expressões de Tabela Comuns (CTEs).

    WHERE

    Suportado para condições de filtro que incluem várias expressões de funções escalares, incluindo funções definidas pelo usuário. Subconsultas como WHERE [NOT] EXISTS <subquery> e WHERE <column> [NOT] IN <subquery> não são suportadas.

    UNION

    Apenas UNION ALL é suportado.

    JOIN

    • INNER JOIN é suportado.

    • LEFT/RIGHT/FULL [OUTER] JOIN não são suportados, exceto nos casos específicos de LATERAL JOIN e lookup join descritos abaixo.

    • [LEFT [OUTER]] JOIN LATERAL com uma expressão de função de tabela (incluindo funções definidas pelo usuário) é suportado.

    • Para lookup join, apenas A [LEFT [OUTER]] JOIN B FOR SYSTEM_TIME AS OF PROCTIME() é suportado.

    Nota
    • Joins implícitos sem a palavra-chave JOIN, como SELECT * FROM a, b WHERE a.id = b.id, são suportados.

    • A computação incremental para INNER JOIN ainda lê todos os dados de ambas as tabelas de origem.

    GROUP BY

    Não suportado.

Exemplos de atualização incremental

Exemplo 1: Processe dados da tabela de origem orders usando funções escalares.

CREATE MATERIALIZED TABLE mt_shipped_orders (
    PRIMARY KEY (order_id) NOT ENFORCED
)
FRESHNESS = INTERVAL '30' MINUTE
AS
SELECT 
    order_id,
    COALESCE(customer_id, 'Unknown') AS customer_id,
    CAST(order_amount AS DECIMAL(10, 2)) AS order_amount,
    CASE 
        WHEN status = 'shipped' THEN 'Completed'
        WHEN status = 'pending' THEN 'In Progress'
        ELSE 'Unknown'
    END AS order_status,
    DATE_FORMAT(order_ts, 'yyyyMMdd') AS order_date,
    UDSF_ProcessFunction(notes) AS notes
FROM 
    orders
WHERE
    status = 'shipped';

Exemplo 2: Enriqueça dados da tabela de origem orders usando LATERAL JOIN e lookup join.

CREATE MATERIALIZED TABLE mt_enriched_orders (
    PRIMARY KEY (order_id, order_tag) NOT ENFORCED
)
FRESHNESS = INTERVAL '30' MINUTE
AS
WITH o AS (
    SELECT
        order_id,
        product_id,
        quantity,
        proc_time,
        e.tag AS order_tag
    FROM 
        orders,
        LATERAL TABLE(UDTF_StringSplitFunction(tags, ',')) AS e(tag))
SELECT 
    o.order_id,
    o.product_id,
    p.product_name,
    p.category,
    o.quantity,
    p.price,
    o.quantity * p.price AS total_amount,
    order_tag
FROM o 
LEFT JOIN 
    product_info FOR SYSTEM_TIME AS OF PROCTIME() AS p
ON 
    o.product_id = p.product_id;

Backfill de dados

Anteriormente, corrigir resultados de processamento de fluxo para dados históricos exigia o desenvolvimento de um job em lote separado. Com tabelas materializadas, faça diretamente o backfill de partições de dados históricos. Essa abordagem unifica o processamento em lote e em streaming, reduzindo custos de desenvolvimento e O&M.

  1. Clique na tabela materializada desejada dentro de seu catálogo.

  2. Na aba Data Information, faça o backfill dos dados.

    Se você definiu uma coluna de particionamento ao criar a tabela materializada, ela será uma tabela particionada. Caso contrário, será uma tabela não particionada.

    Tabela particionada

    Na seção Data Partitions, clique em Trigger Update se esta for a primeira vez que você executa o backfill de dados ou se a partição necessária não existir. Se as partições já existirem, selecione uma partição específica e clique em Refresh na coluna Actions.

    image

    image

    Parâmetros

    • Coluna de particionamento: A coluna de particionamento da tabela. Por exemplo, se você inserir 20241201, todos os dados na partição ds=20241201 passarão por backfill.

    • Nome da Tarefa: O nome da tarefa de backfill de dados.

    • Intervalo de Atualização (Opcional): Especifica se as atualizações devem ser propagadas em cascata para tabelas materializadas downstream. A partir da tabela atual, todas as tabelas materializadas na linhagem de dados são atualizadas. A profundidade máxima suportada da linhagem downstream é de 6 níveis.

      Nota
      • Ao atualizar uma tabela particionada, as tabelas materializadas downstream devem ter exatamente as mesmas colunas de particionamento da tabela inicial. Caso contrário, a operação de atualização falhará.

      • Se uma atualização falhar para qualquer tabela materializada na linhagem, todos os nós downstream subsequentes também falharão.

    • Destino da Implantação: Selecione uma fila ou um cluster de sessão. A seleção padrão é default-queue.

    Tabela não particionada

    Na seção Data Status, clique em Refresh.

    image

    Parâmetros

    • Nome da Tarefa: O nome da tarefa de backfill de dados.

    • Intervalo de Atualização: Esta opção não está disponível para tabelas não particionadas.

      Nota
      • Durante uma atualização, os dados downstream são totalmente atualizados.

      • Se uma atualização falhar para qualquer tabela materializada na linhagem, todos os nós downstream subsequentes também falharão.

      • Atualizações em cascata não são suportadas se a tabela inicial for uma tabela não particionada atualizada por um job de streaming.

    • Destino da Implantação: Selecione uma fila ou um cluster de sessão. A seleção padrão é default-queue.

  3. Backfill agendado e em lote.

    Use a Orquestração de Tarefas para criar um workflow para a tabela materializada executar jobs de backfill conforme um agendamento. Utilize também o recurso de backfill de dados do workflow para fazer backfill de dados em massa para um intervalo de tempo especificado.

Modificar a atualização dos dados

  1. Sob o catálogo correspondente, clique no banco de dados da materialized table e, em seguida, clique na materialized table desejada.

  2. No canto superior direito, clique em Edit Freshness.

    • Se a tabela materializada não tiver uma chave primária, não será possível alternar seu método de atualização entre streaming e lote. O sistema usa um job de streaming para valores de atualização de dados inferiores a 30 minutos e um job em lote para valores de 30 minutos ou mais. Portanto, alterar a atualização além desse limite de 30 minutos não é permitido para tabelas sem chave primária.

    • Se a tabela upstream for uma tabela materializada, garanta que a atualização dos dados da tabela downstream seja um múltiplo inteiro positivo da atualização da tabela upstream.

    • A atualização máxima dos dados é de um dia.

Visualizar linhagem de dados

No painel de navegação à esquerda, escolha Operations Center > Data Lineage para acessar a página de linhagem de dados das tabelas materializadas. Nesta página, visualize as relações de linhagem entre todas as tabelas materializadas. Execute operações como Start/Stop Update e Edit Freshness diretamente em uma tabela materializada. Clique em Details para navegar até a página de detalhes da tabela materializada correspondente.

image

Documentos relacionados