9.4 Views, Materialized Views & Transformation Table Design
Key Takeaways
Standard views store only a query, cost compute every time they are queried, are read-only, and do not automatically pick up changes to their base tables; dropping a base column can leave a view invalid.
Secure views hide their definition from non-owners and disable optimizations that could expose filtered data; use them in a share when consumers must not see the definition (regular views can also be shared), at some cost to performance.
Materialized views (Enterprise Edition) store precomputed results of a single-table query, are maintained by a background service billed as serverless compute, and can be used automatically through query rewrite.
Materialized views cannot use joins, other views, dynamic or hybrid tables, UDFs, window functions, HAVING, ORDER BY, LIMIT, or ROLLUP/CUBE, so multi-table transformations belong in dynamic tables or tasks.
Staging layers usually use transient tables (no Fail-safe, at most one day of Time Travel), while curated layers use permanent tables, dynamic tables, and secure views that give consumers a stable contract.
Why This Decision Matters
Objective 3.3 of the blueprint lists views and tables — their benefits, limitations, and properties; the relationship between views and data types; the impact on costs; dynamic tables; and staging layers and tables. The same business logic can be delivered as a view, a materialized view, a dynamic table, or a table built by tasks, and each choice trades freshness, cost, and flexibility differently.
Standard Views
A view stores a named query; each query against it runs that query.
- No storage cost; every read pays compute on the querying warehouse.
- Read-only — you cannot
INSERTinto a view. - Schema is captured at creation. Changes to a table are not automatically propagated to views on it: a view created with
SELECT *does not gain columns added later, and dropping or changing a referenced column can make the view invalid. Recreate views as part of schema migrations (repeatableR__scripts in migration tools are designed for this). - Data types: a view's columns take their types from its query. Explicit casts in the view (for example
payload:amount::NUMBER(12,2)) turn VARIANT paths into typed, stable columns for consumers; if an upstream type changes, the cast can start failing, so the view is also where type contracts are enforced.
Secure Views
CREATE SECURE VIEW (or ALTER VIEW ... SET SECURE):
- Hides the view definition from roles that do not own it.
- Disables optimizations that could let predicates run before the view's own filters and reveal rows the user should not see.
- Is the usual choice for a share when consumers must not see the definition; regular views can also be added to a share.
- Can be slower than an equivalent standard view because some optimizations are unavailable, so use them where the protection is needed rather than everywhere.
Materialized Views
A materialized view (MV) is a precomputed result of a query, stored and kept current automatically. It is an Enterprise Edition feature.
- Maintenance: a background process applies base-table inserts, updates, and deletes (and reclustering) to the MV. Costs appear as serverless compute (tracked under a Snowflake-provided warehouse named
MATERIALIZED_VIEW_MAINTENANCEand inMATERIALIZED_VIEW_REFRESH_HISTORY) plus storage for the MV's own data. - Always current: if maintenance is behind, Snowflake combines the MV with the newest base-table data, so results are never stale.
- Automatic query rewrite: the optimizer can use an MV for queries against the base table without the query naming the MV.
- Good fits: repeated, expensive aggregations or selective filters on a large, relatively stable table; accelerating queries on external tables (the MV stores data inside Snowflake).
Materialized View Limitations (Frequently Tested)
An MV can query only a single table and cannot:
- Use joins (including self-joins) or query another view, a materialized view, a hybrid table, a dynamic table, or a UDTF.
- Include UDFs (including external functions), window functions,
HAVING,ORDER BY,LIMIT,GROUP BY ROLLUP/CUBE/GROUPING SETS, nested subqueries, orMINUS/EXCEPT/INTERSECT. - Group by keys that are not in the
SELECTlist.
When logic needs joins or window functions, use a dynamic table (Section 9.3) or a task-built table instead.
Comparing the Options
| Option | Storage | Compute cost | Freshness | Main limits |
|---|---|---|---|---|
| View | None | Every query | Always current | Recomputes each time |
| Secure view | None | Every query (fewer optimizations) | Always current | Slower; definition hidden |
| Materialized view | Yes | Serverless maintenance + cheaper reads | Always current | Single table, no joins/UDFs/window functions; Enterprise |
| Dynamic table | Yes | Warehouse refreshes to meet TARGET_LAG | Within target lag | SQL only; refresh-mode rules |
| Table built by tasks/streams | Yes | Warehouse or serverless task runs | As scheduled | You own the MERGE logic |
Staging Layers and Table Types
A common layered design:
| Layer | Purpose | Typical objects | Table type guidance |
|---|---|---|---|
| Landing / raw | Exact copy of source data, often VARIANT | Tables loaded by COPY, Snowpipe, or Snowpipe Streaming | Transient if data can be reloaded from source (no Fail-safe, ≤1 day Time Travel) |
| Staging / cleansed | Deduplicated, typed, conformed data | Dynamic tables, stream+task MERGE targets | Transient or permanent depending on recovery needs |
| Curated / presentation | Business models, marts, shared data | Permanent tables, dynamic tables, MVs, secure views | Permanent (Time Travel + Fail-safe) |
| Scratch | Session-level intermediate results | Temporary tables | Temporary (dropped at session end) |
Cost rules of thumb:
- High-churn staging data in permanent tables accumulates Time Travel and 7 days of Fail-safe for every rewritten micro-partition; transient tables avoid the Fail-safe portion.
- Transient databases or schemas make every table created in them transient by default.
- Views save storage but spend compute on every read; MVs and dynamic tables spend storage and background compute to make reads cheap. Choose based on how often results are read versus how often the base data changes.
Architect Tip: Put secure views (or dynamic tables) at the consumption boundary even when internal layers use plain tables. It gives BI tools and shares a stable column contract while you keep freedom to refactor the layers underneath.
A team wants to precompute a daily revenue summary that joins a 3-billion-row fact table to a product dimension and keep it within 15 minutes of the source. An engineer proposes a materialized view. What should the architect recommend?
A materialized view, because the optimizer will rewrite the join automatically
A secure view, because it caches results for 15 minutes
A dynamic table with TARGET_LAG = '15 minutes', because materialized views cannot contain joins
A standard view with a larger warehouse
A view was created with SELECT * FROM raw.customers. Later, an engineer adds a column loyalty_tier to raw.customers, but queries against the view do not show it. Why?
Views refresh their column list only once per day
Changes to a table are not automatically propagated to views on it, so the view must be recreated to include the new column
SELECT * views only return columns of type VARCHAR
The view is secure, and secure views hide new columns
Which statement about the cost of a materialized view is accurate?
It has no storage cost because it only stores the query text
It is billed only to the warehouse of each user who queries it
It incurs storage for the precomputed results plus serverless background maintenance compute when the base table changes
It is free on Standard Edition and billed only on Enterprise Edition
Sections you finish are checked off in the contents.