데이터베이스 내에서 테이블의 정보를 비공개로 유지하면서 특정 데이터들은 접근 가능하게 할 때는 사용하는 것입니다. view는 단순히 데이터를 쿼리하기 위한 메커니즘입니다. 테이블과 달리 뷰는 데이터 스토리지가 포함되지 않으며, 디스크 공간을 차지할 우려가 없습니다. select 문에 이름을 지정한 다음 다른 사용자가 사용할 수 있도록 쿼리를 저장하여 뷰를 만듭니다. 그런 다음 다른 사용자는 테이블을 직접 쿼리하듯이 뷰를 사용하여 데이터에 액세스할 수 있습니다.
예제
Create view customer_vw
( customer_id,
first_name,
last_name,
email
) as select
customer_id,
first_name,
last_name,
concat(substr(email, 1,2), '***', substr(email, -4) email
From customer
이런 방식으로 기본 테이블에서 email 칼럼의 일부 내용을 숨기고싶고, 다른 데이터에 접근하고싶을 때는 해당 칼럼은 비공개 처리하여 view를 만들어 데이터에 액세스 할 수 있도록 만들 수 있습니다 .
이런 뷰를 작성한 create view 문이 실행될 때 데이터베이스 서버는 나중에 사용하기 위해 뷰 정의를 저장합니다. 쿼리는 실행되지 않으며 데이터가 검색되거나 저장되지 않습니다. 즉, 나중에 view에서 select를 하게 된다면, 해당 우리가 정의해둔 view 쿼리를 실행하고 해당 결과에서 데이터를 가져오는 것입니다.
데이터 보안
테이블을 만들고 사용자가 쿼리할 수 있도록 허용하면 테이블의 모든 열과 모든 행에 액세스 할 수 있습니다. 그러나 테이블에는 식별 번호 또는 신용 카드 번호와 같은 민감한 데이터들이 포함되어 있을 수 있습니다. 이러한 데이터를 모든 클라이언트에게 노출하는 것은 좋지 않기에 해당 테이블은 비공개로 유지하고, 중요한 열을 생략하거나 숨기는 하나 이상의 뷰를 만드는 것입니다.
예를 들어 앞의 예제처럼 중간 문자열을 ** 처리 한다던가, Where절에서 액세스할 수 있는 행을 제한할 수 있습니다.**
데이터 집계
리포팅 애플리케이션에는 보통 집계된 데이터가 필요합니다. 뷰는 데이터를 사전 집계하여 데이터베이스에 저장하는 것처럼 보일 수 있는 좋은 방법입니다.
예를 들어 관리자가 인벤토리에 추가할 새 영화를 결정할 수 있도록 애플리케이션이 영화 카테고리별 총 판매량을 보여주는 보고서를 매월 생성한다고 할때 애플리케이션 개발자가 기본 테이블에 대해 쿼리를 작성할 수 있도록 허용하는 대신 뷰를 제공할 수 있습니다.
이런 방식을 사용하여 데이터베이스 설계자가 굳이 집계하는 별도의 테이블을 만들거나 수정할 필요 없이 필요한 쿼리만 미리 VIEW로 정의해두면 저장 공간을 낭비하지 않고 사용하는 집계기능을 추가한 설계가 가능해집니다.
복잡성 숨기기
뷰를 구현하는 일반적인 이유 중 하나는 최종 사용자를 복잡성으로부터 보호하려는 것입니다. 예를 들어 모든 영화에 대한 정보를 보여주는 보고서가 매달 생성된다고 가정할 때,
이 보고서는 영화 카테고리, 영화 출연 배우의 수, 총 재고 수, 각 영화의 대여 횟수를 보여줘야 합니다.
각 정보는 서로다른 테이블에서 관리되고 있다고 한다면, 많은 join문이 필요합니다. 이런 경우 VIEW를 만들어 해당 조회문을 저장해둔다면, 편하게 사용할 수 있습니다.
CREATE VIEW film_stats
SELECT f.film_id, f.title, f.description, f.rating,
(SELECT .name
FROM category c
INNER JOIN film_category fc ON c.category_id = fc.category_id
WHERE fc.film_id = f.film_id) category_name,
(SELECT count (*)
FROM film_actor fa
WHERE fa.film id = f.film id) num_actors,
(SELECT count (*)
FROM inventory i
WHERE i.film id = f.film_id ) inventory_cnt,
(SELECT count (*)
FROM inventory i
INNER J0IN rental r ON i.inventory_id = r.inventory_id
WHERE i.film id = f.film_id) num_rentals
FROM film f'
| id | title | description | category_name | num_actors | inventory_cnt |
|---|---|---|---|---|---|
| 호러 | 1 | 1 |
추가적으로 이렇게 만들었을 경우 흥미로운 점은 VIEW에서 Select를 할 때 참조하지 않는 서브쿼리는 실행되지 않습니다. 아래와 같이 쿼리를 실행한다면 나머지 num_actors나 inventory_cnt와 같은 서브쿼리는 실행되지 않습니다.
select id, title, description, category_name
from film_stats
분할 데이터의 조인
일부 데이터베이스는 설계 시에 성능을 높이고자 큰 테이블을 여러 조각으로 나눕니다. 예를 들어 payment 테이블이 커지면 설계자는 이 테이블을 최근 6개월의 데이터를 보유하는 payment_current 테이블과 최근 6개월 이전의 모든 데이터를 보유하는 payment_historic 테이블로 나눌 수 있습니다. 만약 고객이 특정 고객에 대한 모든 결제 내역을 보려면 두 테이블을 모두 조회해야 합니다.
이런 경우 두 테이블을 모두 결합하는 VIEW를 생성하여 활용한다면, 기존 테이블과 큰 변함 없이 기본 데이터 구조를 변경할 수 있게 됩니다.
물론 매번 union이 실행된다는 단점이 있어, 세부전략을 잘 선택해야합니다.
데이터 검색에 사용할 뷰 집합을 사용자에게 제공하는 상황에서 사용자도 동일한 데이터를 수정해야 한다면 어떻게 해야할까요? 예를 들어 사용자가 뷰를 사용하여 데이터를 검색하도록하고, update 또는 inser문을 사용하여 기본 테이블을 직접 수정하도록 하는 것은 좀 이상해 보일 수 있습니다.
이런 경우 MySQL, OracleDB 및 SQL 서버는 특정 제한사항을 준수하는 하나의 뷰를 통해 데이터를 수정할 수 있습니다.
MySQL 기준