[Inter SQL] Views
Category: Database System
Tags: SQL
Chapter 4.2에 나오는 View에 대한 내용 정리
View
View(뷰)는 쉽게 말해서 Virtual table로, DB에는 저장되지 않고 query 내부에서만 임시로 저장된다. 원래의 복잡한 테이블에서 필요한 것들만 뽑아서 사용할 수 있는 가상의 테이블 역할을 한다.
Defining View
create view v as < query expression >
예를 들어 instructor 테이블에서 일부 칼럼만 필요한 경우, 필요한 칼럼만 불러오는 query를 수행하면 된다.
select ID, name, dept_name
from instructor;
여기서 View를 사용해서 위에서 필터링 된 테이블을 따로 이름 faculty로 저장할 수 있다.
create view faculty as
select ID, name, dept_name
from instructor
Using View
위에서 정의한 faculty view를 다른 쿼리의 from 구문에 불러와서 사용할 수 있고,
select name
from faculty
where dept_name = 'Biology'
기존에 생성한 view를 사용해서 다른 view를 새롭게 생성할 수도 있다.
create view physics_fall_2017 as
select course.course_id, sec_id, building, room_number
from course, section
where course.course_id = section.course_id
and course.dept_name = 'Physics'
and section.semester = 'Fall'
and section.year = '2017’;
create view physics_fall_2017_watson as
select course_id, room_number
from physics_fall_2017
where building = "Watson";
이렇게 되면 새롭게 생성된 physics_fall_2017_watson 뷰가 기존의 physics_fall_2017 뷰에 대해 의존성을 가지게 된다. 위와 같이 두 개의 view가 직접적으로 연결되어 있을 때 direct dependency을 가진다고 표현한다.
정리하면 view는 테이블에서 필요한 부분만 추출해서 다른 이름의 테이블로 저장할 수 있게 한다.
따라서 view는 :
- 복잡한 쿼리를 단순화 시켜주고,
- 사용자에게 특정 데이터만 보여주기 위한 보안 목적으로 이용 가능하다.
View Expansion
View는 기본적으로 DB에 저장되지 않기 때문에, 실행할 때마다 치환했던 이전 view를 불러온다. 즉, 쿼리를 recursively expansion해서 실행한다.
create view physics_fall_2017_watson as
select course_id, room_number
from physics_fall_2017
where building= 'Watson'
/* 위의 query가 아래와 같이 expansion 되면서 실행됨 */
create view physics_fall_2017_watson as
select course_id, room_number
from (select course.course_id, building, room_number
from course, section
where course.course_id = section.course_id
and course.dept_name = 'Physics'
and section.semester = 'Fall'
and section.year = '2017')
where building= 'Watson';
$V_1$이라는 view를 $E_1$이라는 식에 의해 정의한다고 하면, 이후 $V_2$, $V_3$ 등 view를 계속 만들어낼 수 있다.
이 경우에는 재귀적으로 expansion 되면서 실행하게 된다. 만약 view들이 circular dependency를 가지는 경우, 무한 루프에 빠지게 되어 문제가 발생할 수 있다. 따라서 view들의 관계를 잘 정의하는 것이 중요하다.
View Update
View에 있는 내용을 업데이트하는 방법에는 크게 2가지가 있다.
-
Reject the Insert + Error (보통 view는 read-only)
-
Insert tuple in relation
View를 사용해서 내용을 업데이트(insert, delete 등)하면 여러 문제점이 발생한다.
예를 들어 instructor_info라는 view에 새로운 튜플을 추가한다고 하면 :
create view instructor_info as /* 뷰 생성 */
select ID, name, building
from instructor, department
where instructor.dept_name = department.dept_name;
insert into instructor_info /* 뷰에 새로운 튜플을 추가 */
values ('69987', 'White', 'Taylor');
먼저 instructor에 ('69987', 'White', null, null)
,
그리고 department에 (null, ‘Taylor’, null)
이 삽입된다.
하지만 이렇게 될 경우, view의 where
조건을 만족하지 않기 때문에 view가 업데이트 되지 않는다.
Update in Simple view
대부분의 SQL 개발 환경에서는 view에 업데이트를 할 수 없도록 설정되어 있지만, 일부 Simple view에서는 업데이트가 가능하도록 허용한다.
Simple view의 조건은 다음과 같다 :
from
구문에서 하나의 relation만 불러오는 경우select
구문에서 기존 relation에서 사용하는 이름과 동일한 attribute만을 사용하고, 이 외의 specification(distinct, aggregate 등)이 포함되어 있지 않은 경우select
구문에 포함되지 않은 attribute들에 null 값이 들어갈 수 있어야 함group by
,having
구문이 포함되어 있지 않은 경우
하지만 여기서도 문제점이 발생할 수 있다.
다음과 같이 history_instructors 뷰에 biology instructor 정보를 추가한다면 :
create view history_instructors as
select *
from instructor
where dept_name= 'History';
insert into history_instructors /* 뷰에 새로운 튜플을 추가 */
values ('25566', 'Brown', 'Biology', 100000);
instructor 테이블에는 추가가 되지만, 결국 history_instructors 뷰에는 데이터가 또 삽입되지 않는다. 여기서 check(P)
구문을 사용하면 조건을 만족하지 않는 경우 업데이트 자체를 하지 않도록 설정할 수 있다.
@Database System Concepts sixth edition 내용을 참고함