구체화 뷰

Materialized view

질의 결과를 저장해 빠르게 읽고, 필요할 때 새로고침해 원본 변경을 반영합니다.

···
html
<div class="demo"><div class="head"><b>MATERIALIZED VIEW</b><span>orders count</span></div><div class="stage viewcompare"><div class="metric"><span>source</span><strong id="sourceCount">2</strong><div class="bars"><i></i><i></i><i class="extra" id="newOrder"></i></div></div><div class="metric"><span>stored view</span><strong id="viewCount">2</strong><div class="bars"><i></i><i></i><i class="extra" id="refreshed"></i></div></div></div><div class="foot"><span id="viewstatus">both show 2</span><span>REFRESH</span></div></div>
css
*{box-sizing:border-box}.demo{width:min(96vw,820px);height:min(94vh,350px);padding:clamp(8px,2vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--fg);display:flex;flex-direction:column;gap:clamp(5px,1.5vmin,12px);font:600 clamp(12px,3.5vmin,15px)/1.25 var(--font-sans),sans-serif;overflow:hidden}.head,.foot,.row{display:flex;justify-content:space-between;align-items:center;gap:8px}.head b{color:var(--accent)}.head span,.foot,.muted{color:var(--muted)}.stage{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;gap:8px}.cell,.pill{border:1px solid var(--line);border-radius:8px;background:var(--bg);padding:clamp(4px,1.2vmin,9px);text-align:center}.pill{border-radius:999px}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 17%,var(--surface))!important;color:var(--fg)!important}.bad{border-color:#e16a5d!important;background:color-mix(in srgb,#e16a5d 18%,var(--surface))!important}.foot{font-size:clamp(12px,3vmin,14px)}.viewcompare{justify-content:space-around}.metric{min-width:37%;display:grid;gap:6px;text-align:center}.metric span{color:var(--muted)}.metric strong{font:700 clamp(22px,7vmin,36px) ui-monospace,monospace;color:var(--accent)}.bars{display:flex;gap:5px;justify-content:center}.bars i{width:clamp(15px,4vmin,24px);height:clamp(23px,6vmin,36px);background:var(--accent);border-radius:3px}.bars .extra{opacity:.13;transition:opacity .3s}.bars .extra.on{opacity:1}
js
let n=0;function tick(){document.getElementById('sourceCount').textContent=n?3:2;document.getElementById('viewCount').textContent=n===2?3:2;document.getElementById('newOrder').classList.toggle('on',n>0);document.getElementById('refreshed').classList.toggle('on',n===2);document.getElementById('viewstatus').textContent=['both show 2','source changed · view stale','REFRESH · view shows 3'][n];n=(n+1)%3}tick();const t=setInterval(tick,950);document.querySelector('.demo').onclick=()=>{clearInterval(t);tick()}

구체화 뷰는 질의의 결과를 물리적으로 저장합니다. 복잡한 집계를 반복 계산하지 않아도 되지만, 원본 테이블이 변해도 저장된 결과는 새로고침 전까지 그대로입니다.

데모는 주문 합계가 2에서 3으로 바뀌어도 뷰는 2를 표시하다가 REFRESH 후 3으로 따라잡는 모습을 보여줍니다. 새로고침 비용과 허용 가능한 데이터 지연을 함께 설계해야 합니다.

언제 쓰나

비용이 큰 집계를 여러 번 읽고 약간 늦은 결과를 허용할 수 있을 때 사용합니다.

페이지로 열기 ↗