VIEW는실제 데이터를 저장하지 않는“SELECT 결과를 이름 붙여 저장한 가상 테이블”이다.
실무 SQL은 점점 이렇게 변한다 👇
SELECT ...
FROM orders o
JOIN customers c ON ...
JOIN payments p ON ...
WHERE ...
문제점:
👉 VIEW는 이 문제를 해결한다
CREATE VIEW view_name AS
SELECT ...
FROM ...
WHERE ...;
CREATE VIEW v_order_summary AS
SELECT
o.order_id,
o.ordered_at,
o.status AS order_status,
o.total_amount,
c.customer_id,
c.name AS customer_name,
c.email,
p.payment_id,
p.method AS payment_method,
p.status AS payment_status
FROM orders o
JOIN customers c ON c.customer_id = o.customer_id
LEFT JOIN payments p ON p.order_id = o.order_id;
SELECT *
FROM v_order_summary
WHERE order_status = 'PAID'
ORDER BY ordered_at DESC;
| 구분 | VIEW | 테이블 |
|---|---|---|
| 데이터 저장 | ❌ | ⭕ |
| 실제 공간 | 없음 | 있음 |
| 최신성 | 항상 최신 | 데이터 시점 |
| 생성 목적 | 가독성/보안 | 데이터 저장 |
| 성능 | 원본 쿼리 영향 | 인덱스 영향 |
“운영자는 고객 이름은 보되,
이메일/전화번호는 못 보게 하자”
CREATE VIEW v_customer_public AS
SELECT
customer_id,
name,
status,
created_at
FROM customers;
GRANT SELECT ON v_customer_public TO 'report_user'@'%';
REVOKE SELECT ON customers FROM 'report_user'@'%';
데이터베이스 선택이 안되어있다면 VIEW이름 앞에 데이터베이스를 명시해줘야한다.
SELECT * FROM v_order_summary;
가능 조건(단순 VIEW):
UPDATE v_customer_public
SET status = 'SUSPENDED'
WHERE customer_id = 5;
-- JOIN + 집계 VIEW
UPDATE v_order_summary SET total_amount = 0;
❌ 실패 (대부분 DB에서)
❌ “VIEW를 쓰면 성능이 좋아진다”
⭕ “VIEW는 성능을 바꾸지 않는다”
성능은 인덱스/쿼리에 달려 있음
| 구분 | VIEW | 서브쿼리 | CTE |
|---|---|---|---|
| 재사용 | ⭕ | ❌ | 제한적 |
| 가독성 | ⭕ | ❌ | ⭕ |
| 저장 | ⭕ | ❌ | ❌ |
| 권한 제어 | ⭕ | ❌ | ❌ |
SHOW FULL TABLES WHERE Table_type = 'VIEW';
SHOW CREATE VIEW v_order_summary;
CREATE OR REPLACE VIEW v_order_summary AS
SELECT ...
DROP VIEW v_order_summary;
뷰는 “생성 5문제 + 활용 5문제” 형태로 구성
Q1. (생성) 고객 기본정보 뷰 v_customers_active 를 생성하시오.
조건: status='ACTIVE' / 컬럼: customer_id, email, name, created_at
create view v_customers_active as
select customer_id, email, name, created_at
from customers
where status = 'ACTIVE';
Q2. (생성) 주문+고객 조합 뷰 v_orders_customer 를 생성하시오.
컬럼: order_id, customer_id, customer_name, status, ordered_at, total_amount
create view v_orders_customer as
select o.order_id, o.customer_id, c.name as customer_name, o.status,o.ordered_at, o.total_amount
from orders o
join customers c on c.customer_id = o.customer_id;
Q3. (생성) 주문상세 확장 뷰 v_order_items_detail 을 생성하시오.
(order_items + products)
컬럼: order_id, order_item_id, product_id, product_name, category, quantity, unit_price, line_amount
create view v_order_items_detail as
select oi.order_id, oi.order_item_id, p.product_id, p.name as product_name, p.category, oi.quantity, oi.unit_price, oi.line_amount
from order_items oi
join products p on p.product_id = oi.product_id;
Q4. (생성) 결제 포함 주문 뷰 v_paid_orders 를 생성하시오.
(orders + payments)
컬럼: order_id, status as order_status, method, paid_amount, paid_at, payment_status
create view v_paid_orders as
select p.order_id, o.status as order_status, p.method, p.paid_amount, p.paid_at, p.status as payment_status
from orders o
join payments p on o.order_id = p.order_id;
Q5. (생성) 고객별 누적 구매액 뷰 v_customer_total_spend 를 생성하시오.
(orders + customers)
컬럼: customer_id, customer_name, total_spend, order_cnt
create view v_customer_total_spend as
select c.customer_id, c.name as customer_name, sum(o.total_amount) as total_spend, count(o.order_id) as order_cnt
from customers c
left join orders o on c.customer_id = o.customer_id
group by c.customer_id, customer_name;
Q6. (활용) v_customers_active에서 가입일 최신 5명을 조회하시오.
select *
from v_customers_active
order by created_at desc
limit 5;
Q7. (활용) v_orders_customer에서 최근 14일 주문만 조회하시오. (정렬: ordered_at DESC)
select *
from v_orders_customer
where ordered_at >= now() - interval 14 day
order by ordered_at desc;
Q8. (활용) v_order_items_detail에서 category='DEVICE' 상품의 총 판매수량을 조회하시오.
(출력: product_id, product_name, total_qty)
select product_id, product_name, sum(quantity) as total_qty
from v_order_items_detail
where category = 'DEVICE'
group by product_id, product_name;
Q9. (활용) v_paid_orders에서 결제수단별 결제합계를 조회하시오. (출력: method, total_paid)
select method, sum(paid_amount) as total_paid
from v_paid_orders
group by method;
Q10. (활용) v_customer_total_spend에서 total_spend TOP 5를 조회하시오.
select * from v_customer_total_spend
order by total_spend desc
limit 5;