postgresql에는 materialized view가 있습니다. 간단하게 실습하면서 알아보겠습니다.

 


 먼저, materialized view는 아래와 같이 생성합니다. create materialized view ~ as ~. 위 문장은, m_a라는 이름의 view를 생성하는데요. select * from a가 들어왔습니다. 테이블 a의 내용을 모두 출력하는 쿼리에 대한 뷰를 만듭니다. 그러면 view와 같은 것이 아니냐? 라는 질문을 하실 수 있는데요. 쿼리의 결과가 사용된다는 점은 같습니다.

 

 그런데, 차이가 있습니다.

 먼저, 테이블 a에 들어있는 내용입니다.

 

 이 테이블에 위 2개의 레코드를 추가해 보겠습니다.

 

 

 그리고, view 하나를 생성해 보겠습니다. 이 view는 a의 전체 내용을 출력하는 쿼리를 참조합니다. 무슨 이야기냐면, 이 상태에서, 우리가 select * from v_a; 라는 쿼리를 수행하면, v_a라는 view가 a 테이블에 있는 전체 내용을 출력하는 쿼리를 참조하니까, 해당 쿼리를 수행합니다.

 

 그러면 요래 됩니다. 이 view는 민감한 정보를 다른 유저가 못 보게 할 때에도 쓰인다고 관련 글에서 언급한 적이 있었습니다. 예를 들어, 책의 이름과 저자와 이메일이 있는 테이블이 있다고 해 봅시다. 이 중에서 이메일은 민감 정보이니, reader 권한만 가지는 유저는 못 읽게 할 수 있을 겁니다.

 

 이럴 때, select name, author from book; 이라는 쿼리를 참조하는 view를 하나 만들어서, 해당 view에 읽기 권한을 주면 됩니다.

 

[관련글]

view를 생성해서 column 권한을 주는 방법을 알아봅시다.


 select * from m_a;를 해 봅시다. 아무 것도 나오지 않음을 볼 수 있어요. 제가 m_a라는 실체화된 뷰를 하나 생성했습니다. 그리고 나서, 테이블 a에 레코드 2개를 추가했습니다. 그럼에도 반영이 안 된 것은 어딘가에 materialized view의 결과를 저장하고 있었는데, 새로운 결과가 어딘가에 반영이 되지 않았기 때문입니다. 

 

 그러면 어떻게 해야 할까요? refresh 명령을 이용하면 됩니다.

 

  refresh materialized view m_a;를 입력해 봅시다.

 

 다음에, select * from m_a; 를 입력해 보겠습니다.

 

 그러면 데이터 2개가 새로 생성되었음을 볼 수 있습니다. 정리하면, view와는 다른 점은 결과 데이터를 저장하고 있는 무언가가 있다는 것입니다. refresh를 해야, 새로운 결과가 업데이트 된다는 것입니다. 쉽게 말하면 create materialzed view v_a as select * from a; 라는 것으로 뷰를 생성했다 해 보겠습니다.

 

 그러면 이 시점에서, 테이블 a를 조회했을 때의 결과를 v_a가 가지고 있습니다.

 

 

 별개의 공간에 가지고 있습니다.

 

 따라서 a라는 테이블에 c라는 레코드가 추가되어도, m_a에는 아무런 영향이 없습니다.

 

 하나 놓치면 안 되는 것이 있습니다. matrialized view는 인덱스를 선언할 수 있습니다. 인덱스를 걸 수 있기 때문에, 효율적인 = 연산이나 < 연산이 필요할 때 보다 효율적인 결과를 낼 수 있을 겁니다.