48 CREATE VIEW
A view is a named, saved SELECT. You query it like a table, but the rows are computed on the fly every time — nothing is stored. Views are excellent for hiding complexity (a big join lives behind a short name), enforcing column-level access (grant SELECT on the view but not the underlying table), and giving applications a stable interface as the schema underneath evolves. PostgreSQL also supports materialized views, which do store rows; that is the next lesson.
What you’ll learn
- Creating and replacing views with
CREATE OR REPLACE VIEW - Updatable views and the rules they must follow
WITH CHECK OPTIONto enforce that updates stay within the view- Granting view-level access without exposing the underlying table
- Listing and dropping views
Example
Views are virtual: every SELECT against the view re-runs the underlying query. There is no caching — the view is essentially a macro the planner inlines. That makes views free of staleness but also means they offer no performance benefit on their own; they are about abstraction, not speed.
Updatable views — those that map cleanly to a single underlying table without aggregates, joins, DISTINCT, or set operations — accept INSERT, UPDATE, and DELETE. The action affects the underlying table. WITH CHECK OPTION is the safety belt that prevents an UPDATE from moving a row out of the view’s predicate.
CREATE OR REPLACE VIEW updates the definition if the view already exists. The column list and types must remain compatible — you cannot remove columns or change their types this way. Use ALTER VIEW ... RENAME COLUMN to rename a column; other incompatible changes may require drop and recreate.
Run the example
To run (requires customers_example and orders_example):
Common pitfalls
- Views are not magic performance — every query inlines them. For repeated heavy work, consider a materialized view.
- Updatable view rules are strict: any aggregate,
DISTINCT,GROUP BY, set operation, or multiple base tables typically makes the view non-updatable. You can writeINSTEAD OFtriggers to allow writes anyway, but that is advanced. CREATE OR REPLACE VIEWmust preserve existing column names, order, and types, even when there are no dependents. It can append columns; useALTER VIEWfor a rename.- Views can hide expensive joins, so a one-liner against a view may execute as a multi-second query. Inspect with
EXPLAIN.
Views are an underused tool for application security. Grant the application role SELECT only on a view that returns just the columns it should see (e.g. excluding password_hash). The underlying table remains protected.
Create a view that lists customers without orders (HAVING count(o.id) = 0). Use \d customer_orders in psql to inspect a view. Then create an UPDATE-able view scoped to one customer and update through it — observe the underlying table change.
Downloads
SQL file: create-view.sql · All lesson files · Setup guide