뷰
뷰란 테이블은 아니지만, 사용자가 테이블처럼 사용하는 데이터베이스의 개체 중 하나이다.
놀랍게도, 뷰의 실체는 SELECT 문이며, 뷰를 호출하는 순간 뷰에 있던 SELECT문이 호출되는 형태로 진행된다. 자세한 과정은 조금 뒤에서 다룬다.
뷰는 하나의 테이블과 연관되어 있을 때, 그러니까 JOIN을 사용하지 않았을 때 단순 뷰라고 부르며,
JOIN을 사용하여 여러 테이블과 연관되어 있을 때는 복합 뷰라고 부른다.
뷰의 생성
뷰는 아래의 SQL문 형식으로 생성할 수 있다.
CREATE VIEW 뷰_이름
AS
SELECT 문;
실제 예시를 확인해보자. member 테이블이 존재하는데, 그 중에서 원하는 column만 뽑아와서 뷰를 만든 것이다.
CREATE VIEW v_member
AS
SELECT mem_id, mem_name, addr FROM member;
우리가 사용하는 SELECT문과 비슷하게, SELECT에 WHERE도 당연하게 넣을 수 있다. 아래는 원하는 값만 추출하여 뷰를 만든 형태이다.
SELECT mem_name, addr FROM v_member
WHERE addr IN ('서울', '경기');
위 두 예제에서 볼 수 있듯이, 뷰를 생성할 때는 뷰임을 명확하게 알 수 있도록 이름 앞에 v_를 넣는 것이 일반적이다.
뷰의 작동
뷰가 어떻게 작동되는 지를 알아보자.

- 사용자는 뷰에 조회 또는 변경문을 사용하여 실행한다.
- 뷰에서는 실제 테이블에 자신의 SELECT문과 함께 쿼리를 실행한다.
- 해당 쿼리의 결과를 뷰로 가져온다.
- 뷰는 해당 결과를 사용자에게 보여준다.
뷰의 사용 이유
보안
뷰를 사용함으로써 실제 테이블을 숨길 수 있다. 원하는 특정 열만을 뽑아내거 뷰를 만들면 다른 민감한 정보를 노출시키지 않을 수 있기 때문에, 보안에서 이점이 있다.
SQL의 단순화
만약 뷰를 이용하지 않고 아래와 같은 복잡한 쿼리를 반복적으로 실행해야한다면 복잡하고 번거롭다.
SELECT B.mem_id, M.mem_name, B.prod_name,
M.addr, CONCAT(M.phone1, M.phone2) '연락처'
FROM buy B
INNER JOIN member M
ON B.mem_id = M.mem_id;
그럴 때, 뷰를 만들어 사용하면 편리하다.
CREATE VIEW v_memberbuy
AS
SELECT B.mem_id, M.mem_name, B.prod_name,
M.addr, CONCAT(M.phone1, M.phone2) '연락처'
FROM buy B
INNER JOIN member M
ON B.mem_id = M.mem_id;
뷰의 작동
뷰를 생성할 때, 참조하는 테이블의 이름과 다르게 열 이름을 지정할 수 있다. 뷰를 선언할 때 작성하는 SELECT문에 별칭(alias)를 사용함으로써 가능하다.
별칭은 한글, 띄어쓰기가 가능하지만 선언 후 뷰를 호출하고자 할 때, 띄어쓰기가 존재한다면 백틱(`)을 사용해 묶어주어야 한다.
또한 한글을 사용하게 되면, 한글을 지원하지 않는 OS에서는 오류가 있을 수 있으므로 권장하지 않는다.
CREATE VIEW v_viewtest1
AS
SELECT B.mem_id 'Member ID', M.mem_name AS 'Member Name',
B.prod_name "Product Name", CONCAT(M.phone1, M.phone2) AS "Office Phone"
FROM buy B
INNER JOIN member M
ON B.mem_id = M.mem_id;
SELECT DISTINCT `Member ID`, `Member Name` FROM v_viewtest1;
뷰를 수정하기 위해서는 ALTER TABLE과 유사한 ALTER VIEW를 사용한다.
ALTER VIEW v_viewtest1
AS
SELECT B.mem_id 'Member ID', M.mem_name AS 'Member Name',
B.prod_name "Product Name", CONCAT(M.phone1, M.phone2) AS "Office Phone"
FROM buy B
INNER JOIN member M
ON B.mem_id = M.mem_id;
SELECT DISTINCT `Member ID`, `Member Name` FROM v_viewtest1;
뷰의 삭제는 DROP VIEW이다. 이처럼 테이블의 문법과 유사한 형태를 가지고 있음을 알 수 있다.
뷰의 여러가지 키워드
뷰도 테이블과 마찬가지로, 기존에 있는 뷰와 같은 이름으로 생성하고자 한다면 오류가 발생한다. 이 때, CREATE OR REPLACE 키워드를 사용한다면, 기존 뷰가 삭제되고 새롭게 생성되는 작동을 한다.
DESCRIBE 로 뷰의 정보를 확인할 수 있다(테이블도 가능하다). 하지만 DESCRIBE를 뷰에 사용하게 되면 PK의 정보가 표시되지 않는다.
SHOW CREATE VIEW로 뷰가 생성될 때의 소스코드를 확인해볼 수 있다.
뷰 사용 시 주의점
만약 뷰가 참조하는 테이블(이하 참조 테이블)의 일부 열만을 참조한다고 하자. 이렇게 된다면 뷰를 통해서 데이터를 삽입하려고 할 때, 참조 테이블의 NOT NULL 조건이 있는 열을 뷰가 참조하지 않았다면 삽입이 불가능할 것이다.
이러한 경우에서는 아래와 같은 3가지 방법으로 해결할 수 있다.
- 뷰에서 NOT NULL 열을 포함하도록 재정의
- 참조 테이블에서 NOT NULL 속성인 열을 NULL로 바꾸기
- 참조 테이블에 DEFAULT 키워드를 통해서, 뷰에서 값을 지정하지 않아도 자동으로 입력될 값 설정해주기
또 이러한 상황을 가정해보자. 만약 아래와 같이 height가 167 이상인 데이터만 가져올 수 있도록 뷰를 생성했다고 해보자.
CREATE VIEW v_height167
AS
SELECT * FROM member WHERE height >= 167 ;
SELECT * FROM v_height167;
하지만 이와 반대로 우리가 데이터를 입력할 때, 167 미만의 데이터를 입력하게 된다면 어떻게 될까?
INSERT INTO v_height167 VALUES('TRA', '티아라', 160);
당연하게 정상적으로 수행될 것이다. 하지만 167 이상의 height만 조회할 수 있는 뷰에서 167 이하의 데이터를 입력하는 행위는 썩 좋지 않아보인다.
이럴 때, WITH CHECK OPTION을 활용하여 뷰에서 설정된 값의 범위가 벗어나는 값은 입력되지 못하게 설정할 수 있다.
ALTER VIEW v_height167
AS
SELECT * FROM member WHERE height >= 167
WITH CHECK OPTION;
INSERT INTO v_height167 VALUES('TOB', '텔레토비', 165);
이렇게 하게 된다면 167 미만의 데이터를 입력하여도 데이터가 입력되지 않는다.

'CS > DB' 카테고리의 다른 글
[혼공SQL] 인덱스 내부 작동 (1) | 2024.02.01 |
---|---|
[혼공SQL] 인덱스의 개념 (0) | 2024.01.30 |
[혼공SQL] 제약 조건 (0) | 2024.01.29 |
[혼공SQL] 혼공단 11기 - 4주차 미션 인증 (0) | 2024.01.28 |
[혼공SQL] 혼공단 11기 - 3주차 미션 인증 (0) | 2024.01.17 |