When working with relational databases like PostgreSQL, you often need to simplify complex queries, enforce data security, or speed up reporting. That’s where Views come in.
A view is essentially a virtual table defined by a query. Instead of writing the same complex query again and again, you save it as a view and query it like a table.
In this blog, we’ll explore the different types of views in PostgreSQL, their use cases, pros and cons, examples, and best practices.
🏷️ Types of Views in PostgreSQL
1. Simple View
📌 What is it?
A view built from a single table without joins or aggregations.
✅ Why use it?
- Hide unnecessary columns
- Simplify queries
- Enforce limited access
CREATE TABLE employees ( id SERIAL PRIMARY KEY, name TEXT, department TEXT, salary NUMERIC, active BOOLEAN ); -- Simple view showing only basic employee info CREATE VIEW employee_public_info AS SELECT id, name, department FROM employees; SELECT * FROM employee_public_info;
⚖️ Pros: Lightweight, updatable, always real-time
⚖️ Cons: Doesn’t reduce computation cost
2. Complex View
📌 What is it?
A view involving joins, group by, or aggregates.
✅ Why use it?
Simplify reporting queries
Centralize business logic
CREATE TABLE sales ( id SERIAL PRIMARY KEY, employee_id INT, amount NUMERIC, sale_date DATE ); -- Complex view: total sales per department CREATE VIEW department_sales AS SELECT e.department, SUM(s.amount) AS total_sales FROM employees e JOIN sales s ON e.id = s.employee_id GROUP BY e.department; SELECT * FROM department_sales;
⚖️ Pros: Great for dashboards, reduces repeated SQL code
⚖️ Cons: Usually not updatable, may be slow on large datasets
3. Materialized View
📌 What is it?
A pre-computed, stored result set of a query. Unlike normal views, it stores data on disk.
✅ Why use it?
Speed up expensive queries
Power analytics dashboards
CREATE MATERIALIZED VIEW monthly_sales AS SELECT DATE_TRUNC('month', sale_date) AS month, SUM(amount) AS total FROM sales GROUP BY DATE_TRUNC('month', sale_date); -- Refresh when new data arrives REFRESH MATERIALIZED VIEW monthly_sales; SELECT * FROM monthly_sales ORDER BY month;
⚖️ Pros: Huge performance boost, can be indexed
⚖️ Cons: Data can get stale, needs manual refresh
4. Updatable View
📌 What is it?
A view where you can INSERT, UPDATE, DELETE rows directly.
✅ Why use it?
- Provide restricted updates without exposing full table
-- Only active employees CREATE VIEW active_employees AS SELECT * FROM employees WHERE active = true; -- Update via the view UPDATE active_employees SET active = false WHERE id = 3;
⚖️ Pros: Secure way to allow controlled updates
⚖️ Cons: Works only with simple queries
5. Read-Only View
📌 What is it?
A view that cannot be updated (complex logic, joins, or aggregates).
✅ Why use it?
- Safely expose analytics reports
-- Employees with high sales CREATE VIEW top_performers AS SELECT employee_id, SUM(amount) AS total_sales FROM sales GROUP BY employee_id HAVING SUM(amount) > 50000; SELECT * FROM top_performers;
⚖️ Pros: Safe for reporting
⚖️ Cons: Can’t modify data through it
6. Recursive View
📌 What is it?
A view built using a recursive CTE to handle hierarchies.
✅ Why use it?
- Org charts, folder structures, category trees
-- Hierarchy of employees and managers CREATE VIEW employee_hierarchy AS WITH RECURSIVE emp_cte AS ( SELECT id, name, manager_id FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.id, e.name, e.manager_id FROM employees e JOIN emp_cte c ON e.manager_id = c.id ) SELECT * FROM emp_cte; SELECT * FROM employee_hierarchy;
⚖️ Pros: Perfect for recursive data
⚖️ Cons: Can get slow for deep hierarchies
🛒 Real-World Example: Views in an E-commerce App
Imagine you’re building an e-commerce platform. Here’s how different views fit in:
Simple View →
customer_directory
(hide sensitive columns)Complex View →
category_revenue
(total revenue per category)Materialized View →
daily_sales
(fast dashboards with precomputed data)Updatable View →
active_products
(only allow editing active products)Read-Only View →
top_customers
(find VIPs safely)Recursive View →
category_hierarchy
(nested categories navigation)
By mixing these types, your database becomes secure, performant, and easy to query.
⚡ Performance Best Practices
-
Index Materialized Views
CREATE UNIQUE INDEX idx_daily_sales_date ON daily_sales(order_date);
Refresh Strategy
- Refresh materialized views with `REFRESH MATERIALIZED VIEW` at scheduled times (e.g., nightly with `pg_cron`).
- Optimize Complex Views
- Break into smaller views or switch to materialized views if performance is bad.
-
Use
WITH CHECK OPTION
for updatable views
CREATE VIEW active_products AS SELECT * FROM products WHERE is_active = true WITH CHECK OPTION;
-
Recursive Views: Add Depth Limit
WHERE p.depth < 10;
🏆 Key Takeaways
Use simple & complex views for query simplification and security.
Use materialized views for performance-heavy reporting.
Use updatable views with care.
Use recursive views for hierarchical data.
Always balance freshness vs performance.
With the right type of view, you can make your PostgreSQL database faster, safer, and easier to work with 🚀
Top comments (0)