뷰(View)는 하나 이상의 테이블을 기반으로 한 가상 테이블이다. 실제 데이터를 저장하지 않고 정의된 쿼리를 실행하여 결과를 반환한다. 복잡한 쿼리 캡슐화, 보안 제어, 레거시 호환성 유지에 활용된다.
뷰 생성과 활용
sql
-- 복잡한 조인을 뷰로 캡슐화
CREATE VIEW order_summary AS
SELECT
o.id,
u.name AS customer_name,
u.email,
COUNT(oi.id) AS item_count,
SUM(oi.price * oi.quantity) AS total_amount,
o.status,
o.created_at
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN order_items oi ON o.id = oi.order_id
GROUP BY o.id, u.name, u.email, o.status, o.created_at;
-- 뷰를 일반 테이블처럼 사용
SELECT * FROM order_summary WHERE status = 'pending';
SELECT customer_name, SUM(total_amount) FROM order_summary GROUP BY customer_name;
보안을 위한 뷰
sql
-- 민감한 컬럼(salary, password) 숨기기
CREATE VIEW public_employees AS
SELECT id, name, department, title -- salary 제외
FROM employees;
-- 특정 부서만 보이는 뷰 (행 수준 보안)
CREATE VIEW my_department_employees AS
SELECT * FROM employees
WHERE department = current_setting('app.current_department');
-- 뷰에만 권한 부여 (원본 테이블 접근 차단)
GRANT SELECT ON public_employees TO app_user;
REVOKE SELECT ON employees FROM app_user;
업데이트 가능한 뷰 조건
| 조건 | 설명 |
|---|
| 단일 기본 테이블 | 여러 테이블 조인 뷰는 불가 |
| GROUP BY 없음 | 집계 뷰는 업데이트 불가 |
| DISTINCT 없음 | 중복 제거 뷰 불가 |
| 서브쿼리 없음 | WHERE 절 서브쿼리 포함 시 불가 |
sql
-- INSTEAD OF 트리거로 업데이트 불가 뷰도 처리
CREATE TRIGGER update_order_summary_view
INSTEAD OF UPDATE ON order_summary
FOR EACH ROW EXECUTE FUNCTION handle_order_update();
| 항목 | 뷰 | 구체화된 뷰 | 테이블 |
|---|
| 데이터 저장 | X (쿼리 정의만) | O (스냅샷) | O |
| 읽기 성능 | 쿼리 실행 시간 | 빠름 | 빠름 |
| 최신성 | 항상 최신 | 갱신 필요 | 항상 최신 |
| 인덱스 | 불가 | 가능 | 가능 |
관련 개념