Virtual generated columns

가상 생성 열

PostgreSQL 18 supports generated columns computed when read.

···
html
<div class="demo"><div class="head"><b>GENERATED ALWAYS AS</b><span>virtual</span></div><div class="stage calc"><div class="cell">price<br><strong>12</strong></div><span>×</span><div class="cell">qty<br><strong id="qty">2</strong></div><span>=</span><div class="cell total">total<br><strong id="total">24</strong></div></div><div class="foot"><span id="calcstatus">read computes 12 × 2</span><span>not stored</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)}.calc{justify-content:space-around}.calc .cell{min-width:24%}.calc strong{font:700 clamp(18px,6vmin,28px) ui-monospace,monospace;color:var(--accent)}.calc>span{color:var(--muted)}.total{transition:.3s}
js
let n=0;function tick(){let qty=n?3:2;document.getElementById('qty').textContent=qty;document.getElementById('total').textContent=12*qty;document.getElementById('calcstatus').textContent='read computes 12 × '+qty;document.querySelector('.total').classList.toggle('on',!!n);n=1-n}tick();const t=setInterval(tick,1100);document.querySelector('.demo').onclick=()=>{clearInterval(t);tick()}

A virtual generated column defines an expression that is evaluated when the row is read. In PostgreSQL 18, virtual is also the default kind of generated column.

The demo changes quantity and recomputes total without a separate update. Reads pay the computation cost, so compare it with a stored generated column for the workload.

When to use

Use it when a value can always be derived from other columns and should stay consistent.

Open as page ↗