15. [SQL기초] 뷰 만들기

뷰의 개념

뷰는 데이터를 보는 관점을 제공하는 데이터베이스의 객체입니다. 관점이라는 것이 조금 어려울 수 있는데, 쉽게 말해 쿼리문을 사용해 필요로 하는 결과 데이터를 가져와서 보는 것을 데이터를 보는 하나의 관점이라고 할 수 있습니다. 쿼리문으로 가져온 데이터는 테이블 전체의 내용일 수도 있지만, 여러 테이블에서 모아서 가져온 전혀 새로운 데이터일 수도 있습니다.

뷰는 이렇게 쿼리문으로 가공해서 가져오는 데이터를 실제 테이블처럼 사용할 수 있도록 해주는 객체입니다.

뷰는 실제 테이블이 아니며, 객체 안에 데이터가 존재하는 것도 아닙니다. 뷰 객체는 데이터를 가져오는 쿼리문을 가지고 있다, 사용자가 뷰에 접근하면 쿼리문을 실행해서 데이터를 가져와 보여줍니다.

요약하면 실제 테이블의 일부, 또는 다른 테이블과의 조인 결과로 만들어지는 새로운 데이터를 실제 테이블처럼 사용할 수 있도록 만들어주는 기능을 뷰라고 합니다.

뷰 개념도

일종의 가상 테이블이라고 생각하면 쉽습니다. 뷰는 실제 테이블이 아니지만 실제 테이블처럼 동작하며, 테이블에 사용하는 SELECT, INSERT, UPDATE, DELETE 쿼리문을 사용할 수 있습니다. 실제 테이블이 아니기 때문에 쿼리문 사용에 약간의 제약사항이 있지만, 실제 테이블을 사용하는 것처럼 사용할 수 있습니다.


뷰 생성

뷰는 단독으로 실행할 수 있는 쿼리문을 이용해서 생성합니다.

Create view 뷰이름 as SELECT 쿼리문;

상품의 상세 정보들을 취합해서 상세정보들이 모두 있는 상품 정보 테이블을 이름 순으로 정렬해서 보여주는 뷰를 만들어보겠습니다.

Create view product_detail as select a.name as '상품명', b.name as '제조사', c.country as '원산지' from product a left join maker b on a.maker = b.id left join madein c on a.madein = c.id order by a.name asc;

뷰는 단독 실행할 수 있는 SELECT문이면 어떤 쿼리문도 가능합니다.

생성된 뷰를 SELECT문으로 데이터를 가져오려면 다음과 같이 작성합니다.

select * from product_detail;

열 이름은 쿼리문에서 정할 수도 있지만 뷰를 생성하는 명령어에서도 정해줄 수 있습니다. 앞서 만들었던 상품 상세정보를 보여주는 뷰 생성 쿼리문을 다음과 같이 수정할 수 있습니다. 단, 이렇게 뷰 생성 명령어에 열 이름을 부여할 때는 한글 열 이름을 사용할 수 없습니다.

Create view product_detail (p_name, maker, madein) as select a.name, b.name, c.country from product a left join maker b on a.maker = b.id left join madein c on a.madein = c.id order by a.name asc;

뷰 삭제

뷰의 삭제는 drop view 명령어를 사용합니다.

Drop view 뷰이름;

뷰는 쿼리문을 저장해서 가지고 있는 단순한 객체이기 때문에 뷰를 삭제할 때 테이블처럼 상호 참조 제약 때문에 삭제를 할 수 없거나 한 문제가 없습니다.

단, 뷰를 다른 서브쿼리나 테이블 조인에 사용한 경우 뷰가 삭제됨으로 인해서 이런 쿼리문들이 에러가 발생할 수 있습니다.

뷰를 삭제할 때는 다른 쿼리문에서 뷰 이름을 사용하고 있지 않은 지 항상 확인을 먼저 해야 합니다.

Drop view product_detail;

뷰와 성능 이슈

앞서 뷰의 개념을 소개하면서 뷰 객체에 들어있는 것은 쿼리 문이고 사용자가 뷰에 접근하면 쿼리문이 실행되어 뷰 데이터가 생성된다고 했습니다.

하지만 이렇게 매번 쿼리문을 실행해서 데이터를 가져오면 그냥 쿼리문을 실행하는 것과 크게 다를 것이 없습니다. 매번 데이터를 가져와 메모리에 공간을 할당해야 하기 때문에 메모리 공간을 차지하고, 서버의 성능도 그만큼 갉아먹게 됩니다.

뷰로 가져오는 테이블 데이터가 크면 많은 메모리 공간을 차지하면서 데이터베이스의 성능 지연의 원인이 될 수도 있습니다.

그래서 많은 데이터베이스들이 뷰의 성능을 높이기 위한 여러 가지 방법을 사용합니다. 대표적인 것이 캐시입니다. 처음 뷰 쿼리문이 실행되어 결과 테이블 데이터가 생성될 때 데이터의 일부를 메모리 공간에 가지고 있다 다음번 뷰 테이블에 접근하는 요청이 들어오면 캐시로 남겨둔 데이터를 참조하는 것입니다. 캐싱된 데이터는 일반적인 캐시 데이터 관리 방법에 따라 관리를 해주면 됩니다.

뷰로 가져온 원본 데이터가 갱신된 경우 캐시를 만료하고 다음번 뷰 접근을 할 때 새 캐시를 만듭니다.

또는 뷰의 첫 페이지, 또는 전체 뷰에 해당하는 데이터를 실제 테이블처럼 물리적인 공간에 저장해 놓고 뷰 요청이 들어오면 우선 이것을 보여주는 것입니다. 뷰에 접근하면 쿼리문이 실행되면서 결과 데이터를 생성하고, 뷰에 대한 접근이 끝나면 뷰 데이터는 삭제됩니다. 쿼리문 실행 횟수를 현저히 줄일 수 있고, 메모리 할당과 해제에 따르는 성능 저하를 피할 수 있기 때문에 오라클과 같은 일부 데이터베이스는 이런 고급 최적화 기술을 사용하기도 합니다.

그밖에도 뷰는 쿼리문을 그냥 실행하는 것보다 항상 더 빠르게 실행됩니다. 미리 쿼리문을 파싱 하고 컴파일해서 즉시 쿼리문을 실행할 수 있는 상태로 유지하기 때문에 쿼리문 전처리 과정이 필요가 없습니다. 그래서 일반 쿼리문을 실행하는 것보다는 조금 더 빠르게 실행되는 성능상의 이점이 있습니다.