View : JOIN 등의 작업을 해서 만든 '결과 테이블'로 만들어진 → 가상으로 저장된 테이블
View's Purpose : 보안
예로써, Professor 테이블에 민감한 정보 salary 컬럼을 숨기고 싶을 때 salary 외의 pid name dept 정보만 보게끔 함으로써 보안목적을 달성한다.
일반 view를 만들기 위해서는:
CREATE VIEW v as [쿼리문];
salary를 제외한 view를 만들기 위해서는:
CREATE VIEW myProfessor as SELECT pID, name, dept FROM Professor;
컴퓨터 부서의 모든 교수이름을 찾기 위해서는:
SELECT name FROM myProfessor WHERE dept='컴퓨터';
View테이블은 일반테이블과 타르게 튜플을 실제 View 내부에 저장하지 않는데, 이 때문에 View를 Virtual relation 혹은 Virtual table이라고도 한다. 그 반대로 우리가 일반적으로 아는 실제 테이블을 Base relation 혹은 Base table 이라고 한다.
그런데, 최신 데이터라 함은 View가 Base table로 만들어졌기에 항상 Base table보다는 최신일 수밖에 없다는 뜻이다. Base table을 변경했을 때 View또한 자동적으로 변경되기 때문이다.
특정 응용 분야에서는 새로운 뷰를 정의할 때 자신 뷰를 이용하여야 하는데, 이러한 뷰를 순환뷰(recursive view)라고 한다. 새로운 뷰를 자신 뷰를 이용하여 정의하는 순환뷰는 비순환뷰와 전혀 다르게 처리하여야 하며, 자세한 내용은 본 장 후반부에서 다루기로 한다.
View의 확장이라기보다는 사실 View의 원리에 가깝다.
변환 과정은 뷰 정의가 베이스 관계만으로 구성될 때까지 진행이 되며, 치환되는 뷰가 순환 뷰가 아니면 상기 치환 연산은 궁극적으로 종료된다.
결과적으로, 변환된 질의문에는 더 이상 뷰가 존재하지 않고 베이스 테이블로만 구성이 되며, 이를 데이터베이스 시스템이 평가하여 질의 결과를 구한다.
View 확장의 예는 다음과 같다:
### (1) View 를 만듬
Create view myFaculty as
select pID, name, deptName
from professor
where salary > 50000;
### (2) 위에서 만든 myFaculty 뷰를 사용
Create view myFacultyCS as
select pID, name
from myFaculty
where deptName = CS;
### (3) The above view can be expanded:
### 어렵게 써놨는데 그냥 (2)의 myFacultyCS뷰가 아래구문으로 치환된다는 것이다.
Create view myFacultyCS as
select pID, name
from professor
where deptName = ‘CS’ and salary>50000;
View는 가상의 테이블이지만, View는
뷰에 대한 SELECT 연산 외에 뷰에 대한 변경(즉, INSERT, DELECT, UPDATE) 연산도 가능하다. 뷰에 대한 변경 연산은 뷰를 정의하고 있는 Base table에 대한 변경 연산으로 치환되어 수행이 되는데, 뷰에 대한 속성으로 인한 제약만 충족한다면 충분히 변경연산이 가능하다.
아래 예제에서 myProfessor 뷰에 대한 입력 연산은 Base table인 professor 에 대한 입력 연산으로 치환이 되며, 아래 예제는 문제없이 베이스 테이블에 입력 연산이 수행된다. professor 테이블의 salary 속성에는 널 값이 지정됨을 주목하자.
Create view myProfessor as select pID, name, dept from professor;
INSERT INTO myProfessor VALUES (’12345’, ’Lee’, ’CS’);
를 하면 되는데 실제로 치환되는 구문은 다음과 같다:
INSERT INTO myProfessor VALUES (’12345’, ’Lee’, ’CS’, null);
여기서 null은 salary column의 값이다.
CREATE VIEW professorInfo as
select pID, name, building
from professor, department
where professor.deptName = department.deptName;
INSERT INTO professorInfo values('2345','White', 'Vision Hall');
위 쿼리를 입력하면 아래와 같이 2개의 테이블에 각각 들어갈 것 처럼 보인다.
하지만, 그렇지 않다.
이 경우에 professor 테이블에만 새로운 튜플이 입력되어야 하는지, 또는 department 테이블에만 새로운 튜플이 입력되어야 하는지, 또는 두 테이블 모두에게 새로운 터플이 입력되어야 하는지, 또한 사용자 입력 값에 없는 deptName을 어떻게 정해야 하는지 등 Base table을 수정하는 데에 모호한(ambiguous)한 점이 많아, professorInfo 테이블에 대한 입력 연산을 지원할 수 없다
즉, 2개의 relation의 경우에는 View에서 삽입이 불가능하다. Base relation이 하나일 경우에만 뷰의 변경이 가능하다.
집계함수에 대한 경신을 베이스 테이블에 반영하기는 명확한 방법이 없으므로, 이러한 변경 연산도 지원할 수 없다.
위 조건들을 다 충족할 경우 뷰의 변경이 가능하다.!
### View 생성
Create view CSProfessor as
select *
from professor where deptName= ’CS’;
### View 변경
Insert into CSProfessor values (’255’, ’Brown’, ’EE’, 100000);
뷰 변경 연산 과정에서 고려하여야 하는 다른 사항이다. 상기 CSProfessor 뷰는 변경 가능한 뷰이며, 그래서 <255, Brown, EE, 100000> 튜플은 CSProfessor 뷰에 입력이 가능하며 실제로는 베이스 테이블 professor에 해당 튜플이 입력된다.
그러나 입력된 새 튜플은 CSProfessor 뷰를 통하여 입력이 확인되지 않으며, 그 이유는 입력 튜플의 deptName 속성이 EE이기 때문이다. 사용자 관점에서는 입력된 튜플이 테이블에 존재하지 않는다는 잘못된 인식을 할 수 있다. 일반 사용자는 실제로는 CSProfessor가 뷰 테이블인지 베이스 테이블인지 인식 못하기도 한다.
“with check option"은 이러한 점을 해결하고자 하며, 갱신된 뷰를 통하여 갱신 효과를 사용자가 볼 수 있을 경우에만 뷰 갱신을 허용한다.
사용법은 create문 마지막에 with check option
을 쓰면된다.
뷰는 일반 테이블과 다른 특성을 가지고 있어, 사용법에 있어 제약 사항이 존재한다.
뷰에 대한 색인은 불가능하다. 뷰는 터플을 가지고 있지 않아 뷰에 대한 색인은 의미가 없다.
뷰에 대한 키 속성 또는 무결성 제약을 정의할 수 없다