본문으로 건너뛰기

뷰

정보처리기사 목차SQL 고급레슨 98 / 233

목차

뷰(VIEW)는 기본 테이블에서 SELECT 문으로 뽑아 만든 가상의 테이블입니다. 행을 따로 저장하지 않고 SELECT 문만 저장해 두었다가, 뷰를 조회할 때마다 기본 테이블에서 행을 가져옵니다.

컴퓨터 학과 조교는 컴퓨터 학과 학생의 학번·이름·학년만 보면 됩니다. 조회할 때마다 WHERE 학과코드 = 'CS'를 붙일 수도 있지만, 이 SELECT 문을 뷰로 저장해 두면 테이블처럼 이름 하나로 부를 수 있습니다. 조교에게 학생 표 대신 뷰만 보게 하면 다른 학과 학생과 쓰지 않는 열을 감출 수 있습니다. 기본 테이블에 열이 더해져도 뷰를 쓰는 쪽은 그대로 둘 수 있습니다. 앞에서 배운 논리적 데이터 독립성입니다. 필기는 뷰의 특징과 장단점을 묻고, 실기는 CREATE VIEW 문을 쓰게 합니다.

5단계 중 1단계. 뷰의 바탕이 되는 실제 테이블을 기본 테이블이라고 합니다.

1뷰가 저장하는 것은 SELECT 문이다

뷰의 바탕이 되는 실제 테이블을 기본 테이블(base table)이라고 합니다. 여기서는 학생 표입니다. CREATE VIEW로 뷰를 만들면 기본 테이블 위에 창이 열린 것처럼, 조건에 맞는 행과 고른 열만 보입니다. 컴퓨터학생 뷰에는 CS 3행의 학번·이름·학년이 보입니다. 뷰가 저장하는 것은 행이 아니라 SELECT 문입니다. 그래서 기본 테이블에서 101의 학년을 4로 고치면 뷰에서도 101의 학년이 4로 보입니다. 뷰는 조회할 때마다 기본 테이블을 읽기 때문입니다.

2뷰를 거친 변경과 WITH CHECK OPTION

뷰로 행을 넣으면 그 행은 기본 테이블에 들어갑니다. 108 한지수는 학과코드가 NULL로 들어가 뷰의 조건(CS)에 맞지 않으므로, 넣었는데도 뷰에서는 보이지 않습니다. 뷰를 만들 때 WITH CHECK OPTION을 붙이면, 뷰의 조건에 맞지 않는 행을 넣거나 고치는 문장을 막습니다. 같은 INSERT가 오류로 끝납니다. GROUP BY·집계 함수·DISTINCT가 든 뷰는 그대로는 뷰를 거쳐 행을 고치거나 지울 수 없습니다.

3정의는 바꿀 수 없다

뷰의 정의는 ALTER 문으로 바꿀 수 없습니다. 표준 SQL에는 뷰 정의를 바꾸는 ALTER VIEW가 없고, Oracle의 ALTER VIEW도 정의를 바꾸지는 못합니다. 정의를 바꾸려면 뷰를 지우고(DROP VIEW) 다시 만듭니다(CREATE VIEW).

4장점과 단점

  • 장점: 필요한 행과 열만 보여 나머지를 감춥니다(보안). 복잡한 SELECT 문을 이름 하나로 부를 수 있습니다. 기본 테이블에 열이 더해져도 뷰를 쓰는 쪽은 그대로 둘 수 있습니다(논리적 데이터 독립성).
  • 단점: 정의를 ALTER 문으로 바꿀 수 없습니다. 뷰를 거쳐 넣고 고치고 지우는 데 제약이 있습니다. 뷰는 행을 저장하지 않아 뷰 자체에 인덱스를 만들 수 없습니다(Oracle에서 해 보면 ORA-01702 오류).

예제

결과 표는 Oracle에서 돌린 결과입니다. 예제마다 처음부터 돌릴 수 있게 뷰를 만드는 문장부터 씁니다.

뷰 만들기

CREATE VIEW 컴퓨터학생 AS
  SELECT 학번,
    이름,
    학년
  FROM 학생
  WHERE 학과코드 = 'CS';
SELECT *
FROM 컴퓨터학생
ORDER BY 학번;
학번이름학년
101김민수3
102이서준2
103김지민2

기본 테이블을 고치고 뷰로 행을 넣으면

뷰를 만든 뒤 두 가지를 합니다. 기본 테이블 학생에서 101의 학년을 4로 고치고, 뷰로 108 한지수를 넣습니다. 뷰에 학과코드 열이 없으므로 108의 학과코드는 NULL로 들어갑니다.

CREATE VIEW 컴퓨터학생 AS
  SELECT 학번,
    이름,
    학년
  FROM 학생
  WHERE 학과코드 = 'CS';
UPDATE 학생
SET 학년 = 4
WHERE 학번 = 101;
INSERT INTO 컴퓨터학생
VALUES (108, '한지수', 1);
SELECT *
FROM 컴퓨터학생
ORDER BY 학번;
학번이름학년
101김민수4
102이서준2
103김지민2
  • 101의 학년이 4로 보입니다. 뷰를 고친 적이 없어도 기본 테이블의 값이 그대로 보입니다.
  • INSERT는 오류 없이 학생 표에 108을 넣었습니다. 그런데 108은 뷰의 조건 학과코드 = 'CS'에 맞지 않아 뷰에는 없습니다.

WITH CHECK OPTION

뷰의 조건에 맞지 않는 행이 뷰를 거쳐 들어가지 못하게 하려면 WITH CHECK OPTION을 붙입니다. 같은 INSERT가 Oracle에서 ORA-01402(view WITH CHECK OPTION where-clause violation) 오류로 막힙니다.

CREATE VIEW 컴퓨터학생 AS
  SELECT 학번,
    이름,
    학년
  FROM 학생
  WHERE 학과코드 = 'CS'
  WITH CHECK OPTION;
INSERT INTO 컴퓨터학생
VALUES (108, '한지수', 1);

고칠 수 없는 뷰

아래 뷰의 평균은 여러 행을 묶어 계산한 값이라, 90으로 고치려 해도 기본 테이블의 어느 행을 바꿔야 할지 정할 수 없습니다. Oracle은 ORA-01732(data manipulation operation not legal on this view) 오류를 냅니다.

CREATE VIEW 과목평균 AS
  SELECT 과목코드,
    AVG(점수) AS 평균
  FROM 수강
  GROUP BY 과목코드;
UPDATE 과목평균
SET 평균 = 90
WHERE 과목코드 = 'DS';

정의 바꾸기와 지우기

아래는 학년 열을 빼려고 뷰를 지우고 다시 만든 것입니다.

CREATE VIEW 컴퓨터학생 AS
  SELECT 학번,
    이름,
    학년
  FROM 학생
  WHERE 학과코드 = 'CS';
DROP VIEW 컴퓨터학생;
CREATE VIEW 컴퓨터학생 AS
  SELECT 학번,
    이름
  FROM 학생
  WHERE 학과코드 = 'CS';
SELECT *
FROM 컴퓨터학생
ORDER BY 학번;
학번이름
101김민수
102이서준
103김지민

Oracle에서는 지우지 않고 CREATE OR REPLACE VIEW⁠로 정의를 덮어쓸 수도 있습니다.

뷰를 바탕으로 또 다른 뷰를 만들 수 있습니다. 표준 SQL의 DROP VIEW는 뒤에 CASCADE나 RESTRICT를 붙입니다. CASCADE는 이 뷰를 바탕으로 만든 다른 뷰까지 함께 지우고, RESTRICT는 그런 뷰가 있으면 지우지 않습니다. Oracle은 이 두 낱말을 받지 않아(ORA-02000·ORA-03049) 시험 꼴로만 적습니다.

DROP VIEW 컴퓨터학생 CASCADE;
DROP VIEW 컴퓨터학생 RESTRICT;

시험 포인트

  • 필기: 뷰는 SELECT 문만 저장한 가상 테이블이라, 기본 테이블이 바뀌면 뷰에도 그대로 보입니다. 장점은 보안(필요한 행·열만), 복잡한 SELECT 문 감추기, 논리적 데이터 독립성입니다. 단점은 ALTER로 정의를 바꿀 수 없음(DROP 후 CREATE), 뷰를 거친 변경의 제약(GROUP BY·집계·DISTINCT), 뷰 자체에 인덱스를 만들 수 없음입니다. WITH CHECK OPTION은 뷰의 조건에 맞지 않는 변경을 막습니다. DROP VIEW의 CASCADE는 바탕으로 만든 뷰까지 지우고, RESTRICT는 그런 뷰가 있으면 지우지 않습니다.
  • 실기: CREATE VIEW 뷰이름 AS SELECT 문을 씁니다. 이름은 뷰(View), 기본 테이블(Base Table), WITH CHECK OPTION으로 씁니다.

확인 문제

1. 수강 표에서 점수가 80 이상인 행의 학번·과목코드·점수만 보이는 뷰 고득점을 WITH CHECK OPTION을 붙여 만들었습니다. 다음 네 문장 가운데 이 옵션 때문에 막히는 것을 고르세요.

  • ① DELETE FROM 고득점 WHERE 점수 = 95
  • ② UPDATE 고득점 SET 점수 = 90 WHERE 점수 = 85
  • ③ UPDATE 고득점 SET 점수 = 70 WHERE 점수 = 85
  • ④ SELECT * FROM 고득점 WHERE 점수 = 75
정답

③입니다. 이 옵션은 뷰를 거쳐 넣거나 고치는 행이 뷰의 조건 안에 남는지 봅니다. 85를 70으로 고치면 그 행은 점수 >= 80에서 벗어나므로 ORA-01402로 막힙니다.

  • ① 이 옵션이 뷰를 거친 모든 변경을 막는다고 봤습니다. 지우는 문장은 보지 않아 95인 행이 지워집니다.
  • ② 뷰를 거쳐 값을 고치는 일은 모두 막힌다고 봤습니다. 85를 90으로 고쳐도 조건 안에 남아 오류가 없습니다.
  • ④ 조건에 맞지 않는 행을 조회하는 것도 막는다고 봤습니다. 이 옵션은 조회를 막지 않고, 뷰에 75인 행이 없어 0행이 나옵니다.

2. 다음 (가)~(다)에 맞는 이름을 쓰세요. (가)·(나)는 한글 이름과 영문으로 함께, (다)는 SQL 키워드로 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

  • (가) 조교에게 수강 표의 점수를 감추려고 학번과 과목코드만 고른 SELECT 문에 이름을 붙여 저장했습니다. 조교는 그 이름을 표처럼 조회합니다. 행은 따로 쌓이지 않아 조회할 때마다 수강 표를 읽습니다.
  • (나) (가)가 조회될 때마다 실제로 읽히는, 행을 쌓아 둔 쪽입니다.
  • (다) 과목 표에서 학점이 3인 과목만 보이는 (가)를 만들며 끝에 붙인 말입니다. 뒤에 (가)를 거쳐 학점이 2인 과목을 넣으려 하면 오류로 막힙니다.
정답

받는 답: (가) 뷰(View) · (나) 기본 테이블(Base Table) · (다) WITH CHECK OPTION

(가)의 실마리는 'SELECT 문에 이름을 붙여 저장하고 행은 쌓지 않는다', (나)는 '행이 실제로 쌓여 있는 쪽', (다)는 '조건을 벗어나는 행이 들어오는 것을 막는다'입니다.

  • 같은 이름의 다른 꼴: (가)·(나) 한글 이름만 쓰거나 영문만 쓴 꼴 — 문제가 둘을 함께 쓰라고 했습니다.
  • 틀리는 꼴 CHECK — (다)에: 표의 열에 거는 제약 조건입니다. 학년을 1~4로 제한하는 것이 CHECK이고, (다)는 뷰를 만들 때 끝에 붙이는 말입니다.
  • 틀리는 꼴 기본 테이블 — (가)에: 행을 실제로 쌓아 둔 쪽입니다. (가)는 그 위에서 SELECT 문만으로 보이는 쪽입니다.

3. 학과별 학생 수를 보이는 뷰 학과인원을 만들려 합니다. 학과코드와 인원 두 열이 보여야 합니다. (1) CREATE VIEW 문을 쓰고 (2) 그 뷰를 학과코드 순서로 조회한 결과를 표로 쓰세요. (3) 뷰를 거쳐 인원 값을 고치는 UPDATE 문은 어떻게 되는지도 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.

정답
CREATE VIEW 학과인원 AS
  SELECT 학과코드,
    COUNT(*) AS 인원
  FROM 학생
  GROUP BY 학과코드;
SELECT *
FROM 학과인원
ORDER BY 학과코드;
학과코드인원
CS3
EE3
NULL1

학과코드가 NULL인 학생 107도 한 묶음이 되어 3행입니다. 학생이 없는 경영(BA)은 학생 표에 행이 없어 나오지 않습니다. 인원 값을 고치는 UPDATE 문은 ORA-01732 오류로 막힙니다. 인원은 여러 행을 묶어 센 값이라, 5로 고치려 해도 기본 테이블의 어느 행을 바꿔야 할지 정할 수 없습니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

정보처리기사 목차로