[Oracle] 27.뷰(1)


뷰의 개념



뷰(View)는 한마디로 물리적인 테이블을 근거한 논리적인 가상 테이블이라고 정의할 수 있습니다.

뷰를 가상 테이블이라고 하는 이유는 실질적으로 데이터를 저장하고 있지 않지만,

사용자는 마치 테이블을 사용하는 것과 동일하게 뷰를 사용할 수 있기 때문입니다.

뷰는 기본 테이블에서 파생된 객체로서 기본 테이블에 대한 하나의 쿼리문입니다.

뷰를 사용하는 이유는 다음과 같습니다.


  • 복잡한 쿼리를 보다 쉽게 사용하기 위해 사용



  • 다른 유저에게 테이블에 대한 select에 제한을 두고 싶을 때 사용



자세한 것은 이번 장에서 차차 알아가보겠습니다.

뷰 정의하기



일단 두 개의 테이블을 먼저 정의하겠습니다.


CREATE TABLE emp
    AS
        SELECT
            *
        FROM
            employees;

CREATE TABLE dept
    AS
        SELECT
            *
        FROM
            departments;



뷰는 다음과 같이 정의합니다.


CREATE VIEW emp_vw AS
    SELECT
        employee_id "EMPNO",
        first_name|| ' '|| last_name "ENAME",
        department_id "DEPTNO"
    FROM
        emp
    WHERE
        department_id = 30;



그러면 가상의 테이블이 생성되어서 뷰를 통해 조회가 가능합니다.


SELECT *
FROM emp_vw;




image



사용자 딕셔너리



뷰는 물리적인 테이블이 아닌 가상의 테이블이라고 했는데요~

그렇다면 뷰는 어떤 방식으로 저장되는 걸까요?

뷰는 쉽게 말해서 쿼리문입니다~ 쿼리문 형태로 데이터 딕셔너리에 저장되어서 필요 시에 실행되어 테이블처럼 보이는 것입니다.

다음은 데이터 딕셔너리를 조회하는 방법입니다.


SELECT
    *
FROM
    user_views;




image



쿼리문 형태로 저장되어 있는 것을 확인할 수 있습니다.

뷰를 통한 DML 사용



뷰를 통해서도 데이터입력, 삭제, 수정이 가능한데요~!

가상의 테이블인데 이게 무슨 말일까요??

먼저 다음과 같은 뷰가 정의되어 있다고 합시다.


CREATE VIEW emp_vw
AS
select *
from emp
where department_id=20;



그러면 다음과 같이 INSERT 문을 뷰에 사용할 수 있습니다.


INSERT INTO emp_vw VALUES(999,'김','윤아','윤아@윤아.com','','20180701','MK_MAN',5000,'','100',20);
INSERT INTO emp_vw VALUES(888,'아','이유','아이유@아이유.com','','20180701','SA_MAN',10000,'','100',10);




image



앗 그런데 뷰를 조회해보면, 아이유 데이터는 삽입되지 않았네요!

하지만, emp 테이블에는 제대로 삽입되어 있습니다!


image



그 이유는 뷰는 단순히 쿼리문이므로 뷰에 직접적으로 데이터가 삽입되는 것이아니라,

INSERT 문에 뷰가 쿼리문으로 대체되어 뷰가 조회하는 실제 테이블에 데이터가 삽입되기 때문입니다.


다음 두 INSERT문은 같다고 생각하시면 됩니다!


INSERT INTO emp_vw VALUES(888,'아','이유','아이유@아이유.com','','20180701','SA_MAN',10000,'','100',10);

INSERT INTO (SELECT * FROM emp WHERE department_id=20) VALUES(888,'아','이유','아이유@아이유.com','','20180701','SA_MAN',10000,'','100',10);



단, 뷰를 통해 데이터를 삽일할 때 주의할 점이 있는데 속성타입이 기본테이블과 일치해야합니다~

또 기본테이블의 제약조건을 만족시킨 채로 삽입해야합니다!

예를들어,

다음과 같이 기본테이블의 속성을 합쳐서 별칭 준경우


CREATE VIEW emp_vw AS
    SELECT
        employee_id "EMPNO",
        first_name|| ' '|| last_name "ENAME", --속성 합침
        department_id "DEPTNO"
    FROM
        emp;



데이터 삽입이 불가능합니다!


INSERT INTO emp_vw VALUES (500,'KOO KYUNG',10); --삽입불가 (기본테이블과 속성타입 일치X)




image



또, 뷰에는 나타나지 않은 기본테이블 속성에 제약조건이 있는경우에도 데이터 삽입이 불가합니다.

예를 들어 뷰가 다음과 같이 정의되었을 때,


CREATE VIEW emp_vw2 AS
    SELECT
        employee_id,
        first_name,
        department_id
    FROM
        emp;



데이터 삽입이 불가능합니다!


INSERT INTO emp_vw2 VALUES (500,'Koo',10);  --삽입 오류



왜냐하면 뷰에는 나타나지 않은 기본테이블의 last_name 속성의 제약조건이 NOT NULL이기 때문입니다!


image




INSERT문과 마찬가지로 view에 DELETE 문을 사용하면 실제 테이블의 데이터가 삭제됩니다.


DELETE FROM emp_vw WHERE department_id=20; 



하지만, DELETE와 UPDATE 경우에는 VIEW에 조회되는 행만 삭제, 수정 가능합니다!

VIEW는 거의 조회를 위해 사용되기 때문에 DML을 사용하는데 제약이 많더라도 크게 걱정하지않아도 됩니다.

뷰를 사용하는 이유



뷰를 사용하는 첫번째 이유는 복잡하고 긴 쿼리문을 뷰로 정의하면 접근을 단순화시킬 수 있기 때문입니다.


--복잡한 쿼리를 뷰로 정의

CREATE VIEW empinfo_vw AS
    SELECT
        employee_id "사번",
        first_name|| ' '|| last_name "사원 이름",
        e.manager_id "상관 번호",
        e.department_id "부서 번호",
        department_name "부서 이름"
    FROM
        emp e,
        departments d
    WHERE
        e.department_id = d.department_id
        AND d.deparment_id = 20;




-- 자주 사용하는 복잡한 쿼리문을 단순하게 뷰로 정의하여 사용

SELECT *
FROM empinfo_vw;



뷰를 사용하는 두 번째 이유는 보안에 유리하기 때문입니다.

예를 들어 다른 사용자에게 EMP의 사원번호, 이름, 부서번호만을 노출시키고, 다른 속성은 숨기고 싶으면,

실제 테이블에 대한 권한은 주지 않고, 다음과 같이 정의된 뷰에 대한 권한을 주면 됩니다.


CREATE VIEW emp_vw AS
    SELECT
        employee_id "EMPNO",
        first_name|| ' '|| last_name "ENAME",
        department_id "DEPTNO"
    FROM
        emp;