Schema Visualizer
What This Page Shows
The Schema Visualizer displays a visual map of your ClickHouse® database schema. Every table, materialized view, dictionary, and distributed table appears as a card on the canvas. Lines between cards show how data flows between them.
Open it from Schema Tools > Schema Visualizer in the sidebar. This page is read-only and does not create, modify, or delete any tables.
Getting Started
The Schema Visualizer does not draw anything until you tell it what to look at. This is deliberate: rendering an entire production schema at once is slow and overwhelming, so the page starts focused and lets you expand from there.
- When the page loads, you see a single database dropdown ("Select database...") and an empty canvas with the prompt "Select a database to begin".
- Select a database. A second dropdown ("Select table...") appears, with the prompt "Select a table to visualize its relationships". It lists every table, view, materialized view, and dictionary in that database, sorted alphabetically, with its engine kind in parentheses (for example, "events (mt)" or "events_mv (mv)").
- Select a table. The page does a breadth-first traversal from that table, follows every relationship in both directions, and draws only the connected subgraph. The view auto-fits to frame the result. The other controls (search, Columns, load period, Re-layout, and Fit) appear once the page draws the graph, and the controls bar then shows the number of nodes and edges, for example "12 nodes, 14 edges".
This focused approach answers the most common question directly: "what is connected to this table, and how does data flow through it?"
To reset, set the table dropdown back to "Select table...", or the database dropdown back to "Select database...", and the canvas clears.
Understanding the Canvas
Top-to-Bottom Flow
The graph flows from top to bottom. Parent tables (sources) appear at the top, materialized views and other dependent objects sit below them, and target tables land at the bottom. A multi-stage pipeline cascades down the canvas: source table, then the MV that reads it, then the target table the MV writes to, then any further MVs that read that target, and so on. Following the arrows downward traces the path data takes through your schema.
Relationships Cross Database Boundaries
The breadth-first traversal is not restricted to the database you selected. If a table in database staging feeds a materialized view in database analytics that writes to a target in database reporting, all three appear together on one canvas, with edges that connect them. Every node header shows the full database.table name, so you can always see which database an object belongs to. This is the main way to discover cross-database dependencies that are invisible when you inspect one database at a time.
Node Cards
Each card is one ClickHouse® table (or view, MV, dictionary, and so on). A card has:
Header bar: colored by engine type (see the color reference below). It contains:
- An icon for the engine category.
- The table name (truncated with "..." if too long; hover to see the full qualified name).
- The engine abbreviation (for example, "MV" for MaterializedView, "RMV" for Refreshable MV).
- A row count chip with the approximate number of rows (for example, "1.2M"). Hover to see exact rows and bytes.
- A heatmap badge (only on MVs when the heatmap is on) with the INSERT load metric value.
Column list (toggleable): shows up to 14 columns with their names and types. Key columns (part of the primary key or sorting key) appear in red bold text, and columns with default expressions appear in green. If the table has more than 14 columns, a "... N more" message appears at the bottom.
Node Colors
| Header Color | Engine Type | What It Is |
|---|---|---|
| Green | MergeTree family | The main ClickHouse® storage engine. Includes MergeTree, ReplacingMergeTree, AggregatingMergeTree, SummingMergeTree, CollapsingMergeTree, VersionedCollapsingMergeTree, and others. |
| Lilac / Purple | MaterializedView | A continuously-updating query. When you insert data into the source table, the MV runs its query and writes results to a target table. |
| Pink | Refreshable MaterializedView | A materialized view that runs on a schedule (cron), not on every INSERT. Introduced in ClickHouse® 23.x. |
| Blue | Dictionary | An in-memory key-value lookup table. Typically loaded from another ClickHouse® table, PostgreSQL, MySQL, HTTP, or a file. |
| Amber / Orange | Distributed | A virtual table that routes queries and INSERTs to shards across a cluster. Points to a local table on each shard node. |
| Light Gray | View | A saved query (SELECT statement). Does not store data. Evaluated on every read. |
| Warm Gray | Other | Any engine not in the categories above (Memory, Buffer, Null, File, URL, Join, Set, and so on). |
CHOps tunes the palette separately for dark and light themes, so the colors stay vivid and readable on both backgrounds. When you toggle the theme, the node colors and edge colors update automatically within the same session. A legend under the controls bar shows the node colors and edge colors.
Edge Lines
Lines (edges) between cards show relationships. They flow from the bottom of the parent (source) node to the top of the child (target) node, along the top-to-bottom layout.
| Line Color | Relationship Type | What It Means |
|---|---|---|
| Purple / Lilac | MV flow | A materialized view reads from the source table (above) and writes to the target table (below). This is the most common edge type. |
| Blue | Dictionary source | A dictionary loads its data from this source table. |
| Amber / Orange | Distributed shard | A distributed table routes to this local table. |
| Gray | Other dependency | Any other dependency relationship ClickHouse® tracks. |
Each line ends with a filled triangular arrowhead at the target (child) node, which shows the direction of data flow. The arrow color matches the edge color.
Controls
Search
Type a table name or column name in the Search table or column... box. After a brief delay (200ms), non-matching nodes and their edges dim to near-invisible, and the page highlights matching column names inside nodes.
The case-insensitive search matches against the full qualified name (database.table) and all column names.
Database and Table Dropdowns
The first dropdown lists all databases with table counts in parentheses. Selecting one reveals the second dropdown, which lists the tables in that database, sorted alphabetically, with their engine kind. Selecting a table draws its connected subgraph (see Getting Started).
These two dropdowns are the main way to navigate. Rather than scrolling a giant graph, you pick a starting table and the page shows exactly its connected component, however many databases it spans.
Columns Toggle
Click the "Columns" button to show or hide the column lists inside node cards. When columns are hidden, nodes are compact (header only), which gives a high-level view of the schema structure. When columns are shown, you see the column names, types, and key indicators inside each node.
Load Period (Heatmap)
The heatmap shows how much work each materialized view did during a time window. Select a period:
| Option | Behavior |
|---|---|
| Load: off | No heatmap. All edges and nodes use their default colors. |
| Last 1 day | Shows INSERT pipeline activity from the last 24 hours. |
| Last 7 days | Shows activity from the last week. This is the default. |
| Last 30 days | Shows activity from the last month. |
When the heatmap is on, MV nodes that processed INSERTs during the window get a colored badge in their header. The badge color ranges from cool blue (low activity) through green and amber to hot red (highest activity among all MVs). The page also colors and thickens the edge lines from MVs to their target tables in proportion.
If system.query_views_log has no data for the window, no MV gets a badge.
Metric Dropdown
When the heatmap is on, this dropdown selects which metric the colors represent:
| Metric | What It Measures |
|---|---|
| Duration | Total milliseconds the MV spent processing INSERTs. Good for finding slow MVs. |
| Rows written | Total rows written to the target table. Good for finding high-volume pipelines. |
| Bytes written | Total bytes written. Good for finding large data movers. |
| Rows read | Total rows read from the source table. |
| Bytes read | Total bytes read from the source table. |
| Peak memory | The sum of peak memory across all executions. Good for finding memory-hungry MVs. |
| Executions | The number of times the MV fired. Good for finding frequently-triggered MVs. |
The heatmap uses logarithmic scaling, because INSERT volumes typically span many orders of magnitude. A view that processes 10M rows and one that processes 100 rows would both appear mid-range on a linear scale. Log-scale makes both visually distinct.
Re-layout
Recomputes positions for every visible node with the layout algorithm, then fits the result to the viewport. Use it after you drag nodes around and want to return to the clean algorithmic arrangement. Re-layout moves the nodes.
Fit
Zooms and scrolls so all visible nodes fit in the viewport, without moving any node. Fit moves the camera, not the nodes. If you dragged a node into a corner, Fit zooms out to include it where it sits.
Zoom Controls (bottom-left corner)
| Button | Action |
|---|---|
| + | Zoom in (see details) |
| - | Zoom out (see more of the canvas) |
| Fit icon | Auto-zoom and scroll to fit all visible nodes in the viewport |
You can also zoom with the mouse wheel or a trackpad pinch, and pan by dragging the canvas background.
Interacting with Nodes
Clicking
Click a node to select it. Four things happen:
- The sidebar opens on the right with full details about the table.
- All unrelated nodes dim to near-invisible.
- All connected nodes (one hop in either direction) stay bright.
- Connected edges stay fully visible. Unrelated edges dim.
Click the same node again, click the background, or press Escape to deselect.
Dragging
Click and drag a node to move it. Connected edges follow in real time. When you release, the layout snaps to the new position, and other nodes stay where they are.
A drag does not trigger a click, because the page suppresses the click event when the drag distance goes above 4 pixels.
Sidebar Details
The sidebar shows everything known about the selected table:
| Section | Contents |
|---|---|
| Engine | The full engine name with parameters (for example, ReplicatedReplacingMergeTree('/clickhouse/tables/{shard}/events', '{replica}')) |
| Partition by | The partition key expression |
| Order by | The sorting key (ORDER BY from the CREATE statement) |
| Primary key | The primary key (shown only if different from the sorting key) |
| Rows, Bytes | The current row count and storage size |
| Comment | The table comment (if set) |
| Dict source | The dictionary source definition (for dictionary tables) |
| Reads from (N) | A clickable list of tables this node reads from. Click to navigate. |
| Writes to (N) | A clickable list of tables this node writes to, or is depended on by. Click to navigate. |
| CREATE Statement | The complete CREATE TABLE/VIEW/DICTIONARY statement |
Common Scenarios
"I want to understand how a specific MV pipeline works"
- Type the MV name in the search box.
- Click the highlighted MV node.
- The sidebar shows "Reads from" (the source table) and "Writes to" (the target table).
- The canvas dims everything except the pipeline: source, then MV, then target.
- Click the connected tables in the sidebar to navigate through the pipeline.
"Which MVs are the most expensive?"
- Set the Load dropdown to "Last 7 days".
- Set the Metric dropdown to "Duration".
- Look for the reddest badges in the MV node headers.
- The thickest, reddest edges show the busiest INSERT pipelines.
- Click the hottest MV to see detailed stats in the sidebar.
"I want to find all tables that use a specific column name"
- Type the column name (for example, "user_id") in the search box.
- All tables that contain that column stay visible. Others dim.
- Inside each visible table, the page highlights the matching column row.
- Scroll through the results to see which tables share the column.
"The graph is too large and I cannot find my table"
- Use the database and table dropdowns to focus on a single table's connected subgraph, instead of the whole schema.
- Turn off Columns (click the Columns button) for a compact, header-only view.
- Click "Fit" to auto-zoom to the visible nodes.
- Use the search box to highlight a specific table (matching nodes stay bright, the rest dim).
"I have a table and want to know what depends on it"
- Click the table node.
- The sidebar shows "Writes to" with clickable links.
- Each listed table is a materialized view, dictionary, or distributed table that references your table.
- Click any entry to navigate to it and see its dependencies in turn.
"I want to share the schema diagram with my team"
The Schema Visualizer does not have an export button. You can:
- Take a screenshot (Cmd+Shift+4 on Mac, Win+Shift+S on Windows).
- Use the browser's "Save as PDF" feature (Cmd+P or Ctrl+P, then "Save as PDF").
- Zoom out first (click "-" or "Fit") to capture the full schema.
"The heatmap shows no data"
This means system.query_views_log has no entries for the selected time window. Possible causes:
- No materialized views fired during the window.
query_views_logis disabled in the ClickHouse® server config (check thelog_query_viewssetting).- The ClickHouse® user configured in CHOps does not have SELECT permission on
system.query_views_log.
"I selected a table but only one node appeared"
If a table has no tracked dependencies, its connected subgraph is just the table itself, so a single node renders. This is normal for standalone fact tables, staging tables, and utility tables. It can also happen when:
- Someone created the MV or dependency after the page last loaded the schema. Refresh the browser page to re-fetch the schema.
- The dependency runs through a table function (for example,
remote()orurl()), which ClickHouse® does not track in thesystem.tables.dependencies_*arrays. - The related table lives in a system database, which the page filters out by design.
Tips
- The Columns toggle is your complexity dial. Turn columns off for a bird's-eye view and on to inspect specific tables. It is the fastest way to move between overview and detail.
- The heatmap answers "is this MV worth optimizing?" If one MV has 10x the duration of all others, that is where to focus performance work. If you are deciding between MV-A and MV-B, the heatmap gives you data.
- Cross-database edges mean cross-database materialized views or distributed table mappings. These are common in sharded and multi-tenant setups. Because the traversal crosses database boundaries automatically, you see the full pipeline even when it spans several databases.
- A single node is not a bug. If a table shows just one card, that table has no tracked dependencies. Standalone fact tables, staging tables, and utility tables commonly behave this way.
- Refreshable MVs (pink nodes) run on a schedule, not on every INSERT. Their heatmap load may show bursty patterns that match the refresh interval, rather than continuous activity.
- The row count chip in the node header shows approximate current rows. Hover over it to see the exact count and byte size. This updates when the page loads, not in real time.
- Key columns (red bold text in the column list) are part of the primary key or sorting key. They decide how ClickHouse® stores and queries the data, which makes them the most important columns for query performance.
- Default columns (green text) have a DEFAULT, MATERIALIZED, or ALIAS expression. ClickHouse® computes them automatically, and they may not appear in INSERT statements.
Font Reference
| Element | Font | Purpose |
|---|---|---|
| Table names, column names, engine labels | Red Hat Mono (--font-code) | Monospace for identifiers and code |
| Row counts, byte sizes, heatmap values | B612 (--font-chart) | Numbers for metrics |
| Section labels, control labels, legend text | Jakarta Sans (--font-ui) | UI text (inherited from body) |
| CREATE statement in sidebar | Red Hat Mono (--font-code) | Code block |