MySQL에서 VIEW(뷰)는 하나 이상의 테이블을 기반으로 가상의 테이블을 정의하는 강력한 기능이다.
많은 개발자들이 SELECT 쿼리만 가능하다고 생각하지만, 실제로는 뷰를 통해서도 INSERT, UPDATE, DELETE와 같은 DML(데이터 조작)이 가능하다.
단, 몇 가지 제약 조건과 유의사항을 이해하고 접근해야 한다.
🧱 기본 VIEW 생성하기
먼저 기초가 되는 members 테이블을 준비하자.
CREATE TABLE members (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100),
is_active TINYINT(1),
created_at DATETIME DEFAULT NOW()
);
이제 활성 사용자만 조회하는 VIEW를 만든다.
CREATE VIEW active_members AS
SELECT id, name, email
FROM members
WHERE is_active = 1;
✍️ VIEW를 통한 INSERT
뷰는 기본적으로 테이블처럼 INSERT가 가능하다. 단, 뷰 정의에 따라 제약이 있을 수 있다.
INSERT INTO active_members (name, email)
VALUES ('홍길동', 'hong@example.com');
❗ 하지만 위 예제는 에러가 발생한다. 이유는 is_active 컬럼이 뷰에 포함되지 않았기 때문이다.
✅ 해결 방법
뷰를 아래처럼 수정한다.
CREATE OR REPLACE VIEW active_members AS
SELECT id, name, email, is_active
FROM members
WHERE is_active = 1;
이제 아래처럼 INSERT하면 정상적으로 작동한다.
INSERT INTO active_members (name, email, is_active)
VALUES ('이순신', 'lee@example.com', 1);
✏️ VIEW를 통한 UPDATE
뷰에서 수정도 가능하다. 뷰의 컬럼이 단일 테이블에 종속돼 있고, 계산식이나 JOIN이 포함되지 않아야 한다.
UPDATE active_members
SET email = 'updated@example.com'
WHERE id = 2;
뷰를 통해 업데이트하면 원본 테이블이 즉시 변경된다. 뷰는 가상이지만 결과는 실제이다.
🗑️ VIEW를 통한 DELETE
DELETE도 뷰를 통해 가능하다. 조건에 맞는 데이터만 필터링해서 삭제할 수 있다.
DELETE FROM active_members
WHERE id = 3;
삭제 시에도 뷰가 실제 테이블을 기반으로 하기 때문에, 해당 조건에 맞는 레코드가 원본 테이블에서 제거된다.
🚧 VIEW DML의 제약사항
MySQL에서 VIEW를 통한 INSERT / UPDATE / DELETE는 아래 조건을 만족해야 한다.
- 뷰는 단일 테이블 기반이어야 한다.
- 뷰 내 컬럼은 계산식이나 서브쿼리, GROUP BY를 포함하지 않아야 한다.
- 뷰 내 JOIN이나 DISTINCT, UNION, LIMIT 등은 업데이트 불가
- 뷰에 포함되지 않은 컬럼은 NOT NULL 제약이 없어야 INSERT 가능
뷰에서 복잡한 쿼리를 사용할수록 DML 실행은 제한된다. 이럴 때는 INSTEAD OF 트리거 같은 대안을 고려해야 한다.
🔄 WITH CHECK OPTION으로 데이터 무결성 유지
뷰 정의 시 WITH CHECK OPTION을 추가하면, 뷰 조건을 위반하는 INSERT/UPDATE를 방지할 수 있다.
CREATE OR REPLACE VIEW active_members AS
SELECT id, name, email, is_active
FROM members
WHERE is_active = 1
WITH CHECK OPTION;
이제 아래와 같은 시도는 에러가 발생한다.
UPDATE active_members
SET is_active = 0
WHERE id = 2;
조건을 위배하는 변경이 불가능하므로, 뷰의 무결성을 유지하는 데 유용하다.
🧪 실전 예제: 관리 뷰를 통한 회원 조작
CREATE VIEW member_manage AS
SELECT id, name, email, is_active FROM members;
-- 회원 등록
INSERT INTO member_manage (name, email, is_active)
VALUES ('정약용', 'jeong@example.com', 1);
-- 이메일 수정
UPDATE member_manage
SET email = 'jeong_new@example.com'
WHERE id = 5;
-- 탈퇴 처리
UPDATE member_manage
SET is_active = 0
WHERE id = 5;
-- 탈퇴 회원 삭제
DELETE FROM member_manage
WHERE id = 5 AND is_active = 0;
🧷 VIEW 사용 시 실무 팁
- 뷰에 필요한 컬럼은 명시적으로 나열하자.
- 중간 컬럼 생략 시 INSERT가 실패할 수 있다.
- WITH CHECK OPTION은 무결성 유지에 반드시 고려하자.
- DML이 불가능한 경우, 대체 트리거 로직을 설계할 것
🔗 공식 문서 링크
'DB' 카테고리의 다른 글
[MySQL] 트리거로 DELETE 감지: BEFORE / AFTER 완벽 가이드 🗑️ (2) | 2025.07.03 |
---|---|
[MySQL] 트리거로 UPDATE 감지: BEFORE / AFTER 활용법 완전 정복 🛠️ (0) | 2025.07.03 |
[MySQL] 트리거 BEFORE / AFTER INSERT 실무 활용법 🔄 (0) | 2025.07.03 |
[MySQL] WITH CTE로 INSERT / UPDATE / DELETE 처리하는 실전 예제 모음 (0) | 2025.07.03 |
[MySQL] CALL 프로시저 내 DML 실행 완전 정복 가이드 ⚙️ (0) | 2025.07.03 |
[MySQL] LOAD DATA INFILE로 대용량 데이터 빠르게 삽입하는 방법 ⚡ (0) | 2025.07.03 |
[MySQL] DELETE 실패 원인과 해결책 총정리 🧯 (1) | 2025.07.02 |
[MySQL] DELETE + JSON 조건으로 JSON 데이터 기반 삭제 처리하기 (0) | 2025.07.02 |