{"id":6757,"date":"2026-07-12T02:07:05","date_gmt":"2026-07-12T10:07:05","guid":{"rendered":"https:\/\/www.gudusoft.com\/mysql-data-lineage\/"},"modified":"2026-07-12T02:07:05","modified_gmt":"2026-07-12T10:07:05","slug":"mysql-data-lineage","status":"publish","type":"page","link":"https:\/\/www.gudusoft.com\/pt\/mysql-data-lineage\/","title":{"rendered":"MySQL Data Lineage: Trace Column Lineage Through Views and ETL SQL"},"content":{"rendered":"<p><strong>MySQL data lineage<\/strong> is the column-by-column map of how data flows through your MySQL views, <code>INSERT ... SELECT<\/code> jobs, and ETL scripts: which source columns feed each target column, and through which joins, filters, and aggregations. MySQL itself cannot show you this \u2014 <code>information_schema<\/code> describes structure, not dataflow. <a href=\"https:\/\/www.gudusoft.com\/pt\/ferramenta-de-linhagem-de-dados-sql\/\">Gudu SQLFlow<\/a> builds the lineage automatically by parsing your MySQL SQL with a dedicated MySQL dialect parser, producing an interactive, drillable diagram down to individual columns.<\/p>\n\n\n\n<div class=\"wp-block-group alignfull has-background is-layout-constrained\" style=\"background-color:#eef7fb;padding-top:24px;padding-bottom:24px\"><div class=\"wp-block-group__inner-container\">\n\n<p><strong>See it on your own SQL:<\/strong> paste any MySQL view or <code>INSERT ... SELECT<\/code> into the <a href=\"https:\/\/sqlflow.gudusoft.com\/?utm_source=gudusoft&amp;utm_medium=website&amp;utm_campaign=mysql-data-lineage\" target=\"_blank\" rel=\"noreferrer noopener\">Visualizador de linhagem SQLFlow gratuito<\/a>, pick the MySQL dialect, and get a column-level lineage diagram in seconds.<\/p>\n\n<\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Why information_schema can&#8217;t give you MySQL data lineage<\/h2>\n\n\n\n<p>MySQL&#8217;s <code>information_schema<\/code> is a structural catalog. It will tell you that <code>daily_revenue<\/code> has five columns, what their types are, and (via <code>KEY_COLUMN_USAGE<\/code>) which foreign keys point where. What it will never tell you is that <code>daily_revenue.net_revenue<\/code> is computed from <code>orders.amount<\/code> minus <code>orders.discount<\/code>, filtered on <code>orders.status<\/code>, and grouped by <code>customers.region<\/code>.<\/p>\n\n\n\n<p>That dataflow knowledge lives in one place only: the SQL text itself. In a typical MySQL estate that means view definitions (<code>information_schema.VIEWS<\/code> stores the text, but nothing interprets it), the <code>INSERT ... SELECT<\/code> e <code>ON DUPLICATE KEY UPDATE<\/code> statements your ETL jobs run, generated-column expressions in your DDL, and application-side query files. To turn those into lineage, something has to actually parse and semantically resolve the SQL \u2014 expanding <code>SELECIONE *<\/code>, tracing columns through joins, subqueries, and view stacks. That is what SQLFlow does.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A worked example: a reporting table fed by INSERT-SELECT<\/h2>\n\n\n\n<p>Here is the kind of statement that runs nightly in thousands of MySQL-backed reporting setups \u2014 an upsert that aggregates orders into a summary table:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INSERT INTO daily_revenue\n  (report_date, region, order_count, gross_revenue, net_revenue)\nSELECT o.order_date,\n       c.region,\n       COUNT(*),\n       SUM(o.amount),\n       SUM(o.amount - o.discount)\nFROM orders o\nJOIN customers c ON c.id = o.customer_id\nWHERE o.status = 'completed'\nGROUP BY o.order_date, c.region\nON DUPLICATE KEY UPDATE\n  order_count   = VALUES(order_count),\n  gross_revenue = VALUES(gross_revenue),\n  net_revenue   = VALUES(net_revenue);<\/code><\/pre>\n\n\n\n<p>Run this through SQLFlow and it extracts, per target column, both the columns that directly supply its value and the columns that shape the result without landing in it:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Target column<\/th><th>Direct sources<\/th><th>Indirect (impact) influences<\/th><\/tr><\/thead><tbody>\n<tr><td><code>daily_revenue.report_date<\/code><\/td><td><code>orders.order_date<\/code><\/td><td><code>orders.status<\/code><\/td><\/tr>\n<tr><td><code>daily_revenue.region<\/code><\/td><td><code>customers.region<\/code><\/td><td><code>customers.id<\/code>, <code>orders.customer_id<\/code>, <code>orders.status<\/code><\/td><\/tr>\n<tr><td><code>daily_revenue.gross_revenue<\/code><\/td><td><code>orders.amount<\/code> via <code>SOMA()<\/code><\/td><td><code>orders.order_date<\/code>, <code>customers.region<\/code> (GROUP BY), join keys, <code>orders.status<\/code><\/td><\/tr>\n<tr><td><code>daily_revenue.net_revenue<\/code><\/td><td><code>orders.amount<\/code>, <code>orders.discount<\/code> via <code>SOMA()<\/code><\/td><td>same as above<\/td><\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<p>The distinction in the third column matters. <code>orders.status<\/code> never appears in <code>daily_revenue<\/code>, yet changing how it is populated changes every number in the report. SQLFlow models this <strong>linhagem indireta<\/strong> (columns used in <code>ONDE<\/code>, <code>JOIN<\/code>, e <code>AGRUPAR POR<\/code>) as a separate, toggleable relationship type in the diagram \u2014 most lineage tools do not make the distinction at all, and it is exactly what you need for honest impact analysis.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lineage through MySQL views \u2014 including stacked views<\/h2>\n\n\n\n<p>Views are where table-level lineage tools quietly give up. A BI dashboard reads <code>v_regional_kpis<\/code>, which selects from <code>v_completed_orders<\/code>, which selects from <code>orders<\/code> e <code>customers<\/code>. To answer &#8220;what feeds this dashboard column?&#8221;, the lineage engine must resolve column references down through every layer of the view stack, expand any <code>SELECIONE *<\/code> against the underlying definitions, and carry the transformations along.<\/p>\n\n\n\n<p>SQLFlow resolves column references through views, CTEs, subqueries, and star expansion as part of its semantic analysis. Point it at your schema over JDBC and it pulls the DDL and view definitions itself, so the lineage graph reflects the views as they actually exist in the database, not as they exist in a stale migration folder.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Generated columns: lineage inside a single table<\/h2>\n\n\n\n<p>MySQL generated columns embed dataflow directly in the DDL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE order_items (\n  quantity   INT,\n  unit_price DECIMAL(10,2),\n  line_total DECIMAL(12,2) AS (quantity * unit_price) STORED\n);<\/code><\/pre>\n\n\n\n<p><code>line_total<\/code> is never written by any INSERT, so any approach that only watches DML misses its provenance entirely. Because SQLFlow parses the generated-column expression as SQL, <code>line_total<\/code> gets proper lineage edges from <code>quantity<\/code> e <code>unit_price<\/code>, and anything downstream that reads <code>line_total<\/code> traces all the way back to those two physical columns.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How to build MySQL lineage with SQLFlow<\/h2>\n\n\n\n<ol><li><strong>Collect the SQL.<\/strong> Paste statements or upload files into <a href=\"https:\/\/www.gudusoft.com\/pt\/sqlflow-nuvem\/\">Nuvem SQLFlow<\/a>, or connect your MySQL instance over JDBC so SQLFlow reads the DDL and view definitions directly. dbt users can import the dbt manifest.<\/li>\n<li><strong>Parse with the MySQL dialect.<\/strong> SQLFlow uses a dialect-specific MySQL parser (one of 39 dialect parsers, not a generic ANSI grammar), so MySQL-specific constructs like <code>ON DUPLICATE KEY UPDATE<\/code>, backtick-quoted identifiers, and generated columns are analyzed correctly rather than skipped.<\/li>\n<li><strong>Explore and export.<\/strong> Trace any column upstream or downstream in the interactive diagram, toggle indirect lineage on and off, and export the graph as JSON, CSV, or PNG \u2014 or pull it programmatically via the REST API. Since v8.2.3 you can also ask questions in plain English (&#8220;which reports depend on <code>customers.region<\/code>?&#8221;); every table and column the AI cites is validated against the analyzed graph before display.<\/li><\/ol>\n\n\n\n<p>The engine underneath is <a href=\"https:\/\/www.sqlparser.com\/\">General SQL Parser<\/a>, a commercial SQL compiler front-end developed since the mid-2000s and validated against roughly 13,600 per-dialect SQL test fixtures. Lineage quality is a parsing problem before it is anything else, and that regression corpus is what keeps real-world MySQL \u2014 with all its dialect quirks \u2014 from silently falling out of the graph.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What about open-source MySQL lineage options?<\/h2>\n\n\n\n<p>Open-source parsers like <code>sqllineage<\/code> e <code>sqlglot<\/code> handle individual MySQL SELECT and INSERT statements well, and if you need lineage for a handful of straightforward queries inside a Python pipeline, they are a reasonable place to start. Catalog platforms such as DataHub and OpenMetadata are strong at organizing and displaying lineage once it exists. The gap shows up in producing accurate lineage from hard SQL at scale: resolving columns through stacked views using live schema metadata, distinguishing direct from indirect lineage, expanding <code>SELECIONE *<\/code> correctly, and doing it across thousands of scripts. SQLFlow focuses on that extraction problem \u2014 and then feeds the results into the catalogs via its export adapters for DataHub, Microsoft Purview, and OpenMetadata.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When MySQL is only part of the picture<\/h2>\n\n\n\n<p>MySQL is rarely the whole estate. It is often the OLTP source that feeds a warehouse, or one of several engines an ETL layer crosses. SQLFlow parses 39 SQL dialects with the same column-level analysis, so lineage that starts in MySQL and ends in Snowflake, BigQuery, or <a href=\"https:\/\/www.gudusoft.com\/pt\/postgresql-data-lineage\/\">PostgreSQL<\/a> lives in one graph. Enterprise deployments batch-scan estates of 100+ databases and over a million columns, with incremental scans and a persistent lineage repository. For teams that cannot let SQL text leave their network, <a href=\"https:\/\/www.gudusoft.com\/pt\/sqlflow-on-premise-versao\/\">SQLFlow no local<\/a> runs on Docker or Kubernetes fully air-gapped.<\/p>\n\n\n\n<p>To see what the output looks like across a range of real statements \u2014 multi-join inserts, view stacks, stored procedures \u2014 browse the <a href=\"https:\/\/www.gudusoft.com\/pt\/data-lineage-examples\/\">data lineage examples<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Perguntas frequentes<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does building MySQL lineage require access to my data?<\/h3>\n\n\n<p>No. SQLFlow performs static analysis of SQL code and, optionally, schema metadata such as table and view definitions. It never reads table row data. With the On-Premise edition, even the SQL text stays inside your network.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can SQLFlow trace lineage through INSERT &#8230; SELECT &#8230; ON DUPLICATE KEY UPDATE?<\/h3>\n\n\n<p>Yes. The MySQL dialect parser analyzes the full statement: each target column is linked to the source columns in the SELECT, including expressions inside aggregates, and the upsert clause is handled as part of the same dataflow.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Does information_schema contain lineage information?<\/h3>\n\n\n<p>No. <code>information_schema<\/code> describes structure: tables, columns, types, keys, and the raw text of view definitions. It does not interpret any SQL, so it cannot tell you which source columns feed a given target column. Lineage requires parsing the view and DML SQL, which is what SQLFlow does.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How does SQLFlow handle SELECT * in MySQL views?<\/h3>\n\n\n<p>SQLFlow expands <code>SELECIONE *<\/code> against the actual schema (pulled over JDBC or supplied as DDL), so every column that flows through the star gets its own lineage edge instead of one vague table-to-table arrow.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Is there a free way to try MySQL data lineage?<\/h3>\n\n\n<p>Yes. SQLFlow Cloud has a free tier: paste MySQL SQL in the browser and get the column-level diagram immediately. Premium is $49.99\/month; On-Premise is $500\/month or $4,800 one-time per selected database type \u2014 see <a href=\"https:\/\/www.gudusoft.com\/pt\/precos\/\">pre\u00e7os<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Can I export the MySQL lineage into my data catalog?<\/h3>\n\n\n<p>Yes. Export as JSON, CSV, or PNG, query the REST API, or use the built-in export adapters for DataHub, Microsoft Purview, and OpenMetadata in enterprise deployments.<\/p>\n\n\n\n<div class=\"wp-block-group alignfull has-background is-layout-constrained\" style=\"background-color:#60d5f6;padding-top:32px;padding-bottom:32px\"><div class=\"wp-block-group__inner-container\">\n\n<h2 class=\"wp-block-heading\">Map your MySQL dataflow now<\/h2>\n\n\n<p>Paste a view or an INSERT-SELECT into the free visualizer, or talk to us about scanning your whole MySQL estate.<\/p>\n\n\n<div class=\"wp-block-buttons is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/sqlflow.gudusoft.com\/?utm_source=gudusoft&amp;utm_medium=website&amp;utm_campaign=mysql-data-lineage\" target=\"_blank\" rel=\"noreferrer noopener\">Experimente o SQLFlow gratuitamente<\/a><\/div>\n<\/div>\n\n\n<div class=\"wp-block-buttons is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/www.gudusoft.com\/pt\/contato\/\">Solicite uma demonstra\u00e7\u00e3o empresarial<\/a><\/div>\n<\/div>\n\n<\/div><\/div>\n\n\n\n<script type=\"application\/ld+json\">{\n    \"@context\": \"https:\\\/\\\/schema.org\",\n    \"@graph\": [\n        {\n            \"@type\": \"SoftwareApplication\",\n            \"name\": \"Gudu SQLFlow\",\n            \"applicationCategory\": \"DeveloperApplication\",\n            \"applicationSubCategory\": \"SQL Data Lineage Tool\",\n            \"operatingSystem\": \"Web, Linux, Windows, macOS\",\n            \"url\": \"https:\\\/\\\/www.gudusoft.com\\\/mysql-data-lineage\\\/\",\n            \"description\": \"Automated MySQL data lineage: SQLFlow parses MySQL views, INSERT-SELECT ETL, and generated columns with a dedicated MySQL dialect parser to produce interactive column-level lineage diagrams.\",\n            \"featureList\": \"MySQL dialect parser, column-level lineage, indirect\\\/impact lineage, view resolution, SELECT * expansion, generated column lineage, JDBC metadata import, REST API, DataHub\\\/Purview\\\/OpenMetadata export\",\n            \"softwareVersion\": \"8.2.3\",\n            \"offers\": [\n                {\n                    \"@type\": \"Offer\",\n                    \"name\": \"SQLFlow Cloud Free\",\n                    \"price\": \"0\",\n                    \"priceCurrency\": \"USD\"\n                },\n                {\n                    \"@type\": \"Offer\",\n                    \"name\": \"SQLFlow Cloud Premium\",\n                    \"price\": \"49.99\",\n                    \"priceCurrency\": \"USD\",\n                    \"priceSpecification\": {\n                        \"@type\": \"UnitPriceSpecification\",\n                        \"price\": \"49.99\",\n                        \"priceCurrency\": \"USD\",\n                        \"billingIncrement\": 1,\n                        \"unitText\": \"MONTH\"\n                    }\n                },\n                {\n                    \"@type\": \"Offer\",\n                    \"name\": \"SQLFlow On-Premise\",\n                    \"price\": \"4800\",\n                    \"priceCurrency\": \"USD\"\n                }\n            ],\n            \"publisher\": {\n                \"@type\": \"Organization\",\n                \"name\": \"Gudu Software\",\n                \"url\": \"https:\\\/\\\/www.gudusoft.com\\\/\"\n            }\n        },\n        {\n            \"@type\": \"FAQPage\",\n            \"mainEntity\": [\n                {\n                    \"@type\": \"Question\",\n                    \"name\": \"Does building MySQL lineage require access to my data?\",\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": \"No. SQLFlow performs static analysis of SQL code and, optionally, schema metadata such as table and view definitions. It never reads table row data. With the On-Premise edition, even the SQL text stays inside your network.\"\n                    }\n                },\n                {\n                    \"@type\": \"Question\",\n                    \"name\": \"Can SQLFlow trace lineage through INSERT ... SELECT ... ON DUPLICATE KEY UPDATE?\",\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": \"Yes. The MySQL dialect parser analyzes the full statement: each target column is linked to the source columns in the SELECT, including expressions inside aggregates, and the upsert clause is handled as part of the same dataflow.\"\n                    }\n                },\n                {\n                    \"@type\": \"Question\",\n                    \"name\": \"Does information_schema contain lineage information?\",\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": \"No. information_schema describes structure: tables, columns, types, keys, and the raw text of view definitions. It does not interpret any SQL, so it cannot tell you which source columns feed a given target column. Lineage requires parsing the view and DML SQL, which is what SQLFlow does.\"\n                    }\n                },\n                {\n                    \"@type\": \"Question\",\n                    \"name\": \"How does SQLFlow handle SELECT * in MySQL views?\",\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": \"SQLFlow expands SELECT * against the actual schema, pulled over JDBC or supplied as DDL, so every column that flows through the star gets its own lineage edge instead of one vague table-to-table arrow.\"\n                    }\n                },\n                {\n                    \"@type\": \"Question\",\n                    \"name\": \"Is there a free way to try MySQL data lineage?\",\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": \"Yes. SQLFlow Cloud has a free tier: paste MySQL SQL in the browser and get the column-level diagram immediately. Premium is $49.99\\\/month; On-Premise is $500\\\/month or $4,800 one-time per selected database type.\"\n                    }\n                },\n                {\n                    \"@type\": \"Question\",\n                    \"name\": \"Can I export the MySQL lineage into my data catalog?\",\n                    \"acceptedAnswer\": {\n                        \"@type\": \"Answer\",\n                        \"text\": \"Yes. Export as JSON, CSV, or PNG, query the REST API, or use the built-in export adapters for DataHub, Microsoft Purview, and OpenMetadata in enterprise deployments.\"\n                    }\n                }\n            ]\n        }\n    ]\n}<\/script>","protected":false},"excerpt":{"rendered":"<p>MySQL data lineage is the column-by-column map of how data flows through your MySQL views, INSERT &#8230; SELECT jobs, and ETL scripts: which source columns feed each target column, and through which joins, filters, and aggregations. MySQL itself cannot show you this \u2014 information_schema describes structure, not dataflow. Gudu SQLFlow builds the lineage automatically by parsing your MySQL SQL with a dedicated MySQL dialect parser, producing an interactive, drillable diagram down to individual columns. See it on your own SQL: paste any MySQL view or INSERT &#8230; SELECT into the free SQLFlow lineage visualizer, pick the MySQL dialect, and get\u2026<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":5}},"_links":{"self":[{"href":"https:\/\/www.gudusoft.com\/pt\/wp-json\/wp\/v2\/pages\/6757"}],"collection":[{"href":"https:\/\/www.gudusoft.com\/pt\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.gudusoft.com\/pt\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.gudusoft.com\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gudusoft.com\/pt\/wp-json\/wp\/v2\/comments?post=6757"}],"version-history":[{"count":0,"href":"https:\/\/www.gudusoft.com\/pt\/wp-json\/wp\/v2\/pages\/6757\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.gudusoft.com\/pt\/wp-json\/wp\/v2\/media?parent=6757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}