Exemplos de linhagem de dados: 6 cenários reais com SQL e diagramas

UM exemplo de linhagem de dados Mostra, para um trecho concreto de SQL, quais tabelas e colunas de origem alimentam quais colunas de saída e por quais transformações os dados passam ao longo do caminho. Os seis exemplos práticos abaixo abrangem situações que os engenheiros de dados realmente encontram: um simples SQL. INSERIR-SELECIONAREste artigo apresenta uma transformação multi-CTE, uma cadeia de visualizações, um procedimento armazenado com SQL dinâmico, uma cadeia de modelos dbt e um fluxo ETL entre bancos de dados. Cada exemplo fornece o SQL e, em seguida, descreve exatamente como é o grafo de linhagem correspondente.

Todos os exemplos nesta página são reproduzíveis: Cole o SQL no Visualizador de linhagem SQLFlow gratuito e você obtém o diagrama interativo descrito abaixo.

Como ler estes exemplos

Cada grafo de linhagem contém dois tipos de arestas. Uma direto Uma "borda" significa que os dados fluem fisicamente de uma coluna de origem para uma coluna de destino, possivelmente por meio de uma função ou agregação. indireto borda significa uma coluna que molda o resultado sem atingir o limite: colunas usadas em ONDE, JUNTAR, e AGRUPAR POR cláusulas. Ignorar as arestas indiretas é o que leva ao fracasso da análise de impacto, pois remover uma coluna de filtro quebra um relatório tão certamente quanto remover uma coluna selecionada. Se esses termos são novos para você, comece com O que é linhagem de dados? e Como funciona a linhagem em nível de coluna, depois volte.

Exemplo 1: um exemplo simples de linhagem de dados INSERT-SELECT

O ponto de partida para qualquer discussão sobre linhagem: uma declaração que agrega dados em uma tabela de resumo.

INSERT INTO sales_summary (region, total_amount) SELECT c.region, SUM(o.amount) FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.status = 'completed' GROUP BY c.region;

O gráfico de linhagem possui três tabelas (pedidos, clientes, resumo_de_vendas) e estas arestas ao nível da coluna:

Coluna alvoColuna de origemTipo de bordaVia
resumo_de_vendas.regiãoclientes.regiãoDiretocópia simples
resumo_de_vendas.valor_totalpedidos.quantidadeDiretoSOMA()
resumo_de_vendas.*pedidos.statusIndiretoONDE filtro
resumo_de_vendas.*pedidos.id_do_cliente, clientes.idIndiretoJUNTAR doença

Observe o que o gráfico já mostra e que uma visualização em nível de tabela não mostraria: clientes.email e todas as outras colunas intocadas não desempenham nenhum papel aqui, e pedidos.status É importante mesmo que nunca apareça na saída. Muitas ferramentas de linhagem ignoram completamente essa última aresta; o SQLFlow modela a linhagem direta e indireta como tipos de relacionamento separados e alternáveis.

Exemplo 2: transformação multi-CTE

É nos CTEs (Common Traded Events) que os diagramas de linhagem desenhados à mão começam a se situar, pois cada CTE representa uma relação temporária pela qual o grafo deve passar sem perder o rastro das fontes originais.

COM daily AS ( SELECT order_date, customer_id, SUM(amount) AS day_total FROM orders GROUP BY order_date, customer_id ), rated AS ( SELECT customer_id, day_total, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY day_total DESC) AS rn FROM daily ) SELECT customer_id, day_total AS best_day_revenue FROM rated WHERE rn = 1;

O gráfico de linhagem é renderizado. diário e classificado como nós intermediários, portanto, o caminho completo da coluna de interesse é: pedidos.quantidadeSOMA()total diário.diaclassificado.total_do_diamelhor_receita_diáriaA função de janela cria uma cadeia mais sutil: agora é calculado a partir de id_do_cliente (partição) e total_do_dia (pedindo), e então ONDE rn = 1 faz agora uma entrada indireta para cada coluna de saída. Portanto, pedidos.quantidade influências melhor_receita_diária duas vezes: diretamente pela soma e indiretamente pela classificação que decide qual linha permanece. Um resolvedor que só faz correspondência de padrões em nomes de colunas não consegue enxergar esse segundo caminho.

Exemplo 3: uma cadeia de vistas

Empilhamento de visualizações. Em um data warehouse maduro, um relatório geralmente está a três ou quatro definições de visualização de distância das tabelas físicas, e a pergunta "de onde realmente vem esse número?" exige percorrer toda a cadeia.

CRIAR VIEW v_active_customers AS SELECT id, name, email FROM customers WHERE status = 'active'; CRIAR VIEW v_customer_revenue AS SELECT a.id, a.name, SUM(o.amount) AS revenue FROM v_active_customers a JOIN orders o ON o.customer_id = a.id GROUP BY a.id, a.name;

O gráfico mostra v_customer_revenue.revenue traçando o contorno da visão de volta para pedidos.quantidade, com status dos clientes anexada como uma aresta indireta herdada do filtro da primeira visualização. Ela também expõe algo útil na direção oposta: v_active_customers.email é selecionada pela primeira visualização, mas não é consumida por nada posteriormente. Colunas mortas como essa são exatamente o que você deseja encontrar antes de uma limpeza ou migração, e elas são invisíveis no nível da tabela. Quando as definições de visualização usam SELECIONE *O SQLFlow expande a estrela em relação ao esquema, de modo que cada coluna herdada ainda seja resolvida para sua origem física.

Exemplo 4: procedimento armazenado com SQL dinâmico

Este é o exemplo que diferencia as ferramentas de linhagem, pois o nome da tabela de destino sequer existe como texto literal no código. Aqui está um procedimento do SQL Server que cria um snapshot mensal por meio de uma tabela temporária e uma tabela montada dinamicamente. INSERIR:

CREATE PROCEDURE dbo.load_monthly_snapshot @month VARCHAR(7) AS BEGIN SELECT o.customer_id, SUM(o.amount) AS month_total INTO #monthly FROM dbo.orders o WHERE CONVERT(VARCHAR(7), o.order_date, 126) = @month GROUP BY o.customer_id; DECLARE @sql NVARCHAR(MAX) = N'INSERT INTO dbo.snapshot_monthly (customer_id, month_total) ' + N'SELECT customer_id, month_total FROM #monthly'; EXEC sp_executesql @sql; END

O gráfico de linhagem correto supera ambos os obstáculos: pedidos.quantidadeSOMA()#mensal.total_mensalsnapshot_monthly.month_total, com pedidos.data_do_pedido como uma borda indireta através do ONDE cláusula e a @mês parâmetro rastreado como entrada para esse filtro. Para chegar lá, é necessário um analisador sintático procedural T-SQL real (não um divisor de instruções), rastreamento de tabelas temporárias entre instruções e resolução da string SQL passada para sp_executesqlO SQLFlow possui analisadores sintáticos procedurais dedicados para T-SQL do SQL Server e PL/SQL do Oracle, resolve SQL dinâmico dentro de procedimentos e, adicionalmente, renderiza um gráfico de chamadas mostrando quais procedimentos invocam quais, de modo que a linhagem de procedimento para procedimento também fica visível. O SQL dinâmico é o ponto cego mais comum em ferramentas de linhagem; se você for avaliar qualquer ferramenta, teste-a primeiro com esse padrão.

Exemplo 5: cadeia de modelos dbt

O dbt fornece linhagem em nível de modelo pronta para uso. ref()Mas a questão interessante é no nível da coluna: qual campo de origem alimenta qual coluna do data mart, por meio de qual etapa as renomeações são feitas?

-- models/staging/stg_orders.sql SELECT id AS order_id, customer_id, amount, status FROM {{ source('raw', 'orders') }} -- models/marts/fct_customer_revenue.sql SELECT customer_id, SUM(amount) AS lifetime_revenue FROM {{ ref('stg_orders') }} WHERE status = 'completed' GROUP BY customer_id

Importe o manifesto dbt do projeto para o SQLFlow e o grafo resolverá as referências parametrizadas em uma cadeia de colunas concreta: raw.orders.quantidadestg_orders.amountSOMA()fct_customer_revenue.lifetime_revenue, com a renomeação eu iaid_do_pedido preservado no salto de palco e status transportado como uma aresta indireta do filtro do datamart. Como o manifesto vincula os modelos aos objetos do data warehouse que eles criam, o mesmo grafo reconcilia a linhagem gerenciada pelo dbt com tudo o mais que interage com essas tabelas fora do dbt.

Exemplo 6: ETL entre bancos de dados

Os mecanismos de processamento de imóveis abrangem vários aspectos. Um fluxo típico: um banco de dados operacional do SQL Server é extraído para armazenamento em nuvem, carregado no ambiente de teste do Snowflake e, em seguida, transformado em um esquema analítico. O processo de carregamento e transformação se parece com isto:

-- Snowflake COPY INTO staging.orders_raw FROM @s3_extract/orders/; INSERT INTO analytics.fct_orders (order_id, customer_id, amount_usd) SELECT r.order_id, r.customer_id, r.amount * fx.rate FROM staging.orders_raw r JOIN staging.fx_rates fx ON fx.currency = r.currency;

No lado do Snowflake, o gráfico mostra valor_em_dólares como uma coluna calculada com dois pais diretos, pedidos_brutos.quantidade e fx_rates.rate, unidos pela expressão aritmética, mais moeda como uma aresta indireta da condição de junção. Para abranger todo o pipeline, você alimenta o SQLFlow com ambos os lados em seus respectivos dialetos: a lógica de extração T-SQL analisada com o analisador do SQL Server e os scripts do Snowflake analisados com o analisador do Snowflake, de um total de 39 analisadores específicos para cada dialeto. Em implantações corporativas, os resultados são armazenados em um repositório de linhagem persistente que realiza varreduras em lote de conjuntos de mais de 100 bancos de dados e mais de um milhão de colunas, de modo que o panorama completo do SQL Server ao Snowflake reside em um único gráfico e pode ser exportado para o DataHub, Microsoft Purview ou OpenMetadata.

O que todos os seis exemplos têm em comum?

Todos os gráficos acima foram derivados exclusivamente de texto SQL e metadados de esquema. Esse é o método principal por trás de tudo isso. Linhagem de dados baseada em SQLComo a lógica de transformação já reside no SQL, a análise estática desse SQL reconstrói a linhagem sem agentes, sem acesso ao log de consultas e sem nunca ler uma linha dos seus dados. As diferenças entre os exemplos residem apenas na complexidade da análise sintática, partindo de uma única consulta. INSERIR-SELECIONAR para SQL dinâmico dentro de um procedimento.

ExemploO que isso exercitaParte difícil
1. INSERIR-SELECIONARBordas diretas versus indiretasModelagem ONDE/JUNTAR colunas como linhagem
2. Multi-CTERelações intermediáriasEntradas de função de janela; caminho de filtro por classificação
3. Veja a cadeiaDefinições aninhadasExpansão estelar; identificação de colunas mortas
4. Procedimento armazenadoCódigo de procedimentoTabelas temporárias e resolução dinâmica de SQL
5. cadeia dbtSQL com modelosResolvendo ref()/fonte() para objetos reais
6. ETL entre bancos de dadosVários dialetosConsolidando gráficos por motor em um único repositório.

Perguntas frequentes

O que é um diagrama de linhagem de dados?

Um diagrama de linhagem de dados é um grafo direcionado no qual os nós representam tabelas, visualizações ou colunas, e as arestas mostram como os dados fluem entre eles por meio de transformações SQL. Diagramas em nível de coluna, como os descritos nesta página, desenham uma aresta para cada relação coluna de origem-coluna de destino, anotada com a função ou cláusula que a criou.

Posso reproduzir esses exemplos por conta própria?

Sim. Cole qualquer um dos trechos de SQL acima no Visualizador SQLFlow gratuitoBasta selecionar o dialeto correspondente e o diagrama interativo aparecerá em segundos. A versão em nuvem possui um plano gratuito.

Qual a diferença entre linhagem direta e indireta?

A linhagem direta significa que os dados fluem de uma coluna de origem para uma coluna de destino, por exemplo. SOMA(pedidos.quantidade) alimentação montante totalA linhagem indireta significa que uma coluna influencia o resultado sem aparecer nele, como por exemplo... ONDE filtro ou JUNTAR O SQLFlow rastreia ambos como tipos de aresta separados e alternáveis; a maioria das ferramentas captura apenas o fluxo direto.

É possível extrair a linhagem de procedimentos armazenados e SQL dinâmico?

Sim, mas precisa de um analisador sintático procedural, não apenas de um analisador de consultas. O SQLFlow possui analisadores sintáticos dedicados para Oracle PL/SQL e SQL Server T-SQL, rastreia a linhagem por meio de parâmetros e tabelas temporárias, resolve strings SQL construídas dentro de procedimentos e desenha o grafo de chamadas de procedimento para procedimento.

As ferramentas de código aberto conseguem lidar com esses exemplos?

Parcialmente. Bibliotecas como linhagem sql e sqlglot São realmente boas em analisar consultas individuais e lidam bem com os exemplos 1 e 2. Os exemplos que valem a pena testar antes de confirmar são os de 4 a 6: código procedural com SQL dinâmico, linhagem indireta como um tipo de aresta separado e a integração de um conjunto de dados com múltiplos dialetos em um único grafo interativo. Execute seu procedimento armazenado mais complexo em qualquer ferramenta que você avalie e compare os resultados.

Com quais dialetos SQL esses exemplos funcionam?

O SQLFlow fornece 39 analisadores sintáticos específicos para dialetos, incluindo Snowflake, BigQuery, Redshift, Databricks, Oracle, SQL Server, PostgreSQL, MySQL, Teradata, Hive, Spark SQL e Trino. Os exemplos acima usam SQL genérico, T-SQL, SQL com templates dbt e sintaxe Snowflake, e cada um é analisado por sua própria gramática, em vez de uma gramática ANSI genérica.

Transforme seu próprio SQL em um diagrama de linhagem.

Cole uma consulta, um procedimento ou um script completo no visualizador gratuito e obtenha o gráfico em nível de coluna em segundos. Para ambientes com muitos bancos de dados, fale conosco sobre o repositório corporativo.