← warin.me · Data Science and EngineeringEnglish

OLAP → FEATURE ENGINEERING → FEATURE STORAGE

คำนวณจากประวัติศาสตร์ จัดเก็บอย่างมีเจตนา และส่งมอบโดยไม่ทำงานราคาแพงซ้ำทุกครั้ง

OLAP มอบประวัติศาสตร์ ขนาด และ analytical operator ที่ Feature Engineering ต้องใช้ ส่วน Feature Storage เปลี่ยนผลลัพธ์ที่เลือกแล้วให้เป็น data product ที่คงทน สร้าง training ซ้ำได้ มีประสิทธิภาพสำหรับ batch scoring และเมื่อจำเป็นก็เร็วพอสำหรับ online prediction

01

Model

จัดระเบียบ fact, dimension, entity และเวลา

02

Compute

สร้าง window และ point-in-time feature ในระดับใหญ่

03

Store

Materialize ประวัติศาสตร์และค่าล่าสุดอย่างมีเจตนา

04

Serve

เลือก storage ให้เหมาะกับ batch หรือ online latency

01 · REFERENCE ARCHITECTURE

เส้นทาง Feature มีทั้ง Data Plane และ Control Plane

Data Plane เคลื่อนย้ายและคำนวณค่า ส่วน Control Plane นิยามว่าค่าเหล่านั้นหมายถึงอะไร ใครเป็นเจ้าของ ควรสดเพียงใด และมีโมเดลใดพึ่งพาอยู่

OLAP feature engineering and storage reference architectureOperational and event data enter OLAP storage, are modeled into facts and dimensions, transformed into point-in-time features, materialized in offline feature tables and optionally synchronized to an online store. A registry, quality, lineage and orchestration control the whole path. DATA PLANE · VALUES FLOW LEFT TO RIGHT SourcesOLTP · events · APIsfiles · streamsCDC / ELT OLAP Storagewarehouse · lakehousecolumnar files · partitionshistorical snapshotshistory retained Analytical Modelfacts · dimensionsentity spine · event timecleaned business grainreusable layer Feature Computewindows · aggregatesPIT joins · encodingbatch / streamtested definitions Offlinefeature tablehistorytraining Training / Batchdataset · model · scoring Online Storelatest by keyOnline InferenceAPI · low-latency lookup CONTROL PLANE · MEANING, QUALITY AND OPERATIONSRegistry & ownershipSchema & versionsLineage & catalogQuality & driftOrchestrationCost & SLO
ภาพที่ 1 OLAP จัดเตรียมโครงสร้างวิเคราะห์เชิงประวัติศาสตร์ Feature Computation เปลี่ยนโครงสร้างนั้นเป็น input ของโมเดล และ Materialized Store จัดรูป input ให้เหมาะกับ training และ serving

02 · WHY OLAP IS A STRONG FEATURE SOURCE

Feature ต้องการประวัติศาสตร์ การ scan ขนาดใหญ่ และ grain เชิงวิเคราะห์ที่มั่นคง

OLAP ไม่ได้ถูกต้องสำหรับ ML โดยอัตโนมัติ แต่การออกแบบเชิงกายภาพและตรรกะใกล้กับงานคำนวณ Feature มากกว่าฐานข้อมูลระบบงาน

01

เก็บประวัติศาสตร์

Fact, snapshot และ slowly changing dimension ช่วยสร้างสถานะในอดีตซ้ำ แทนการเขียนทับ

02

Grain เชิงวิเคราะห์

ตาราง orders, line items, sessions และ customer-day ระบุชัดว่าหนึ่งแถวหมายถึงอะไร

03

การประมวลผลแบบ Columnar

อ่านเฉพาะคอลัมน์ ตัด partition ที่ไม่เกี่ยวข้อง และบีบอัดค่าซ้ำในการ scan ขนาดใหญ่

04

ประมวลผลแบบขนาน

Distributed engine คำนวณหลาย entity และ time window พร้อมกันได้

05

ชั้นธุรกิจร่วม

Conformed dimension และ metric ที่ review แล้วลดการตีความ source ซ้ำ

06

การกระทบยอด

ตรวจยอดและ coverage ของ Feature เทียบกับ fact ที่กำกับดูแลแล้วก่อนเผยแพร่

03 · HOW OLAP SEES DATA

Transaction หนึ่งรายการกลายเป็น Measure ที่มองผ่านได้หลาย Dimension

OLAP จัดข้อมูลเพื่อเปรียบเทียบข้ามเวลา สินค้า ลูกค้า ภูมิศาสตร์ ช่องทาง และสถานการณ์ Warehouse และ Lakehouse สมัยใหม่ทำ Cube-like Analysis ด้วย Columnar Table และ Distributed Engine

OLAP cube with Time, Market and Instrument dimensions An isometric analytical cube. A highlighted cell represents one aggregate at the intersection of one time period, one market and one instrument. TIMEMARKETINSTRUMENT หนึ่ง CELLหนึ่งพิกัด → หนึ่งผลรวม
MEASURES volume · value · count · return · spread หนึ่ง Cell คือ Aggregation ณ Coordinate หนึ่งชุด
time = 2026-08market = SETinstrument = GOLDcell → SUM(volume), AVG(spread)
SLICE

ตรึงหนึ่ง Dimension

กิจกรรมทองคำเดือนสิงหาคมข้ามทุกตลาด

DICE

เลือก Sub-cube

ทองคำและเงิน ตลาดเอเชีย ช่วง Q1–Q2

DRILL-DOWN

ลงสู่รายละเอียด

ปี → ไตรมาส → วัน → รายการซื้อขาย

ROLL-UP

สรุปขึ้นระดับสูง

หลักทรัพย์ → Sector → ตลาด

PIVOT

เปลี่ยนมุมมอง

ตลาดแยกเดือน แทนเดือนแยกตลาด

WINDOW

เปรียบเทียบตามเวลา

Rolling Demand, Growth และ Volatility

04 · FACT, DIMENSION AND GRAIN

Fact บอกว่าเกิดอะไรขึ้น ส่วน Dimension อธิบายบริบท

ก่อน Aggregate ต้องระบุว่าหนึ่งแถวหมายถึงอะไร Grain รายวัน ระดับ Event และ Snapshot ตอบคนละคำถามและมีต้นทุนต่างกันมาก

DIM_DATE day · week · month · year
DIM_INSTRUMENT symbol · asset_class · sector
FACT_MARKET_OBSERVATION instrument × market × observation_time
price · volume · bid · ask · open_interest
DIM_MARKET exchange · country · session
DIM_SCENARIO actual · forecast · base · stress
instrument × day

ขนาดเล็กสำหรับ Portfolio Research แต่สร้าง Intraday Order Book ซ้ำไม่ได้

instrument × venue × event_time

รองรับ Microstructure แต่ใช้ Storage, Ordering และ Compute สูงมาก

account × month_end

เหมาะกับ Exposure Trend แต่ไม่เห็นการเปลี่ยนแปลงระหว่าง Snapshot

05 · WHERE OLAP IS USED

OLAP รองรับงานที่ต้องเปรียบเทียบหลายแกนก่อนตัดสินใจ

Analytical Model เดียวกันรองรับ Dashboard, Investigation, Planning, Feature Engineering, Control และ Audit

การเงินและตลาด

Liquidity, Exposure, Credit, Fraud, Treasury และ Scenario

ค้าปลีก

Sales Mix, Basket, Promotion, Inventory และ Cohort

การผลิต

Yield, Downtime, Quality, Energy และ Maintenance

โทรคมนาคม

Traffic, Congestion, Quality, Churn และ Incident

บริการสุขภาพ

Capacity, Waiting, Pathway และ Cost ภายใต้ Privacy Control

ϟ

พลังงาน

Demand Curve, Generation, Outage, Weather และ Price

ภาครัฐ

งบประมาณ การให้บริการ ภูมิศาสตร์ โครงการ และ Outcome

ผลิตภัณฑ์ดิจิทัล

Funnel, Retention, Experiment และ Unit Economics

ขยายข้อ 05 · แปลงคำถามธุรกิจให้เป็น Grain, Measure และ Feature ที่ใช้ซ้ำได้

OLAP จะมีประโยชน์เมื่อเราระบุการตัดสินใจให้ชัด “วิเคราะห์ลูกค้า” กว้างเกินไป แต่ “ทุกวันจันทร์ ลูกค้าคนใดมีแนวโน้มหยุดซื้อภายใน 30 วัน” ระบุ entity, observation time, horizon และ action ได้ หลักคิดเดียวกันใช้ได้ทุกอุตสาหกรรม

FINANCE × RETAIL

Exposure, Liquidity และพฤติกรรมลูกค้า

Grain ที่ใช้ได้ เช่น account-day, instrument-minute, customer-week และ basket-line โดยต้องระบุหน่วยเงิน สกุลเงิน venue และ event time ให้ชัด

  • Measure: balance, notional, P&L, volume, net sales, margin และ inventory
  • Feature: utilization_30d, liquidity_gap, basket_diversity_90d, promo_dependency
  • การตัดสินใจ: credit review, treasury allocation, replenishment และ targeted retention
MANUFACTURING × ENERGY

Yield, Reliability และความเข้มการใช้ทรัพยากร

แยก Grain ระดับ machine-cycle, production-batch, asset-hour และ meter-interval ออกจากกัน การยุบรวมทำให้ค่าเฉลี่ยหลอกและซ่อน downtime

  • Measure: good units, scrap, cycle time, kWh, temperature และ outage minutes
  • Feature: rolling_yield_20_batches, vibration_rms_1h, energy_per_good_unit, outage_rate_30d
  • การตัดสินใจ: maintenance window, quality hold, load scheduling และ anomaly investigation
TELECOM × DIGITAL PRODUCT

คุณภาพบริการ เส้นทางผู้ใช้ และการทดลอง

Grain ระดับ network-event, subscriber-hour, session และ experiment-assignment ตอบคนละคำถาม ต้องเก็บเวลา assignment เพื่อไม่ให้ Feature ของ experiment ปนกัน

  • Measure: throughput, latency, dropped sessions, active users, conversion และ revenue
  • Feature: congestion_minutes_24h, failed_session_ratio, funnel_velocity, retention_28d
  • การตัดสินใจ: capacity action, incident triage, churn intervention และ product rollout
HEALTH × GOVERNMENT

Capacity, Pathway และ Outcome ที่ตรวจสอบได้

Grain ระดับ encounter, patient-day, facility-week, service-request และ project-month ต้องมีขอบเขตความเป็นส่วนตัวและ organizational dimension ที่เปลี่ยนตามเวลา

  • Measure: waiting time, occupancy, completed service, budget used และ outcome count
  • Feature: wait_p90_7d, pathway_delay, budget_burn_rate, geographic_coverage_gap
  • การตัดสินใจ: staffing, referral, service prioritization และ programme review ไม่ใช่การตัดสินทางคลินิกอัตโนมัติ

ประโยคออกแบบที่นำกลับมาใช้ได้

ณ [observation time] สำหรับ [entity] แต่ละราย ให้คำนวณ [measure/window] จาก event ที่ระบบรับรู้แล้วในเวลานั้น แยกตาม [dimensions] เพื่อสนับสนุน [decision] ภายใน [horizon]

06 · GOLD DEMAND AND SUPPLY

“Demand ของทองคำ” ไม่ใช่คอลัมน์เดียว แต่เป็นกลุ่มของ Flow ผ่านตลาดหลายประเภท

Physical Flow, ETF Holding, Futures Positioning, Inventory และ Liquidity เกี่ยวข้องกันแต่ใช้แทนกันไม่ได้ OLAP รักษาหน่วย ความถี่ Source และ Publication Time ก่อน Feature Engineering นำมารวม

PHYSICAL SUPPLY การผลิตจากเหมือง country × quarter × tonnes ทองคำรีไซเคิล region × quarter × tonnes
MARKET & INVENTORY Spot / futures currency × venue × timestamp ETF / inventory fund/location × report_date
PHYSICAL DEMAND เครื่องประดับและเทคโนโลยี region/sector × quarter × tonnes การลงทุนและภาครัฐ category × period
FEATURE 01

physical_balance_4q

Physical Supply ลบ Demand โดยรักษา Publication Lag และ Revision

FEATURE 02

etf_flow_zscore_20d

ETF Holding Change เทียบประวัติตนเอง ไม่ใช่ Physical Demand ทั้งหมด

FEATURE 03

futures_curve_slope

สัญญาไกลเทียบสัญญาใกล้โดยควบคุม Roll Convention

FEATURE 04

inventory_change_5d

Inventory Change พร้อม Availability Timestamp

อย่ายุบกลไกต่างชนิดเป็นค่าเดียว

ราคาที่สูงขึ้นไม่ได้พิสูจน์ตรง ๆ ว่า Physical Demand มากกว่า Supply เพราะความคาดหวัง ค่าเงิน อัตราดอกเบี้ย Liquidity และ Positioning มีผลต่อราคาเช่นกัน

ขยายข้อ 06 · สร้าง Feature ทองคำโดยไม่ทำเหมือนทุก Flow เป็นตลาดเดียวกัน

ข้อมูลทองคำมาถึงด้วย Grain และรอบเผยแพร่ที่เข้ากันไม่ได้ Trade อาจละเอียดระดับเสี้ยววินาที ETF Holding รายวัน Inventory รายวันหรือรายสัปดาห์ และ Mine Production รายไตรมาสพร้อม revision ควรเก็บตารางต้นทางแต่ละชนิดก่อน แล้วจึงทำ point-in-time join ด้วยเวลาที่ข้อมูลพร้อมให้ใช้ ไม่ใช่ดูเพียงช่วงเวลาที่ข้อมูลอธิบาย

01 · PHYSICAL BALANCE

physical_balance_4q

ที่ Grain รายไตรมาส แยก mine production และ recycling เป็น supply ส่วน jewellery, technology, bar/coin investment และ official-sector net purchase เป็น demand โดยรักษาหน่วย tonnes และ revision vintage

  • balance = mine + recycling − jewellery − technology − investment − official
  • ค่าบวกคือ categorized surplus ตามนิยามนี้ ไม่ใช่การพยากรณ์ราคาขึ้นลงอัตโนมัติ
02 · ETF FLOW

etf_flow_zscore_20d

แปลง Holding ของกองทุนเป็นหน่วยโลหะเดียวกัน หาผลต่างตาม report date รวมหลัง align source แล้วจึง standardize เทียบประวัติย้อนหลัง

  • flow_t = holding_t − holding_t−1
  • z = (flow_t − mean(flow_20d)) / std(flow_20d)
  • z-score สูงหมายถึง ETF flow ผิดปกติ ไม่ใช่ Demand ทองคำทั้งหมด
03 · FUTURES CURVE

futures_curve_slope

เลือกสัญญาใกล้และไกลตาม roll calendar ที่บันทึกไว้ ห้ามต่อรหัสสัญญาโดยไม่มีกฎ roll

  • slope = (P_deferred / P_nearby − 1) / year_fraction
  • Curve อาจสะท้อน funding, storage, convenience yield, positioning และ liquidity
04 · REPORTED INVENTORY

inventory_change_5d

เก็บ location, inventory category, unit, report date และ available_at พร้อมเก็บ correction เป็น data vintage ใหม่เพื่อสร้าง training ซ้ำได้

  • change_5d = inventory_t − inventory_t−5
  • Reported Inventory เป็น stock ที่มองเห็นได้ส่วนหนึ่ง ไม่ใช่ทองคำทั้งหมดที่โลกนำมาใช้ได้

ตัวอย่างคำนวณรายไตรมาส

mine = 900 t, recycling = 300 t jewellery = 520 t, technology = 80 t investment = 410 t, official = 140 t physical_balance = (900 + 300) - (520 + 80 + 410 + 140) = +50 t ความหมาย: +50 t ภายใต้ classification และ data vintage นี้ ต้องตรวจว่ารายงานเผยแพร่ก่อน observation time แล้ว
ควรเปรียบเทียบFlow ที่หน่วย ช่วงเวลา ขอบเขต และเวลาเผยแพร่สอดคล้องกัน
ห้ามถือว่าเท่ากันETF Flow, Futures Volume, Mine Output และ Physical Consumption
เก็บเป็นบริบทUSD, Real Rate, Inflation Expectation, Volatility และ Market Liquidity

07 · STOCK DEMAND, SUPPLY AND LIQUIDITY

Shares Outstanding, Volume และ Supply ใน Order Book เป็นคนละชั้นการวิเคราะห์

Supply เชิงโครงสร้างเกี่ยวข้องกับ Shares และ Free Float ส่วน Demand/Supply ที่พร้อม Execute ปรากฏเป็น Bid/Ask และ Trade แสดงเฉพาะ Activity ที่จับคู่แล้ว

SELL / ASK 103.00 — 8,200 102.50 — 5,500 102.00 — 3,100
101.75 mid-price · spread 0.50
BUY / BID 101.50 — 4,300 101.00 — 6,800 100.50 — 9,100
Order-book Snapshot แบบจำลอง Displayed Depth เปลี่ยนแปลงได้และไม่ใช่ Total Investor Demand
FEATURE 01

book_imbalance_l1

สัดส่วน Displayed Bid/Ask ที่ Align ตาม Venue และเวลา

FEATURE 02

relative_spread

Quoted Spread หาร Mid-price เป็น Liquidity Descriptor หนึ่งตัว

FEATURE 03

turnover_20d

Volume เทียบ Free Float ที่ปรับ Corporate Action

FEATURE 04

realized_volatility_20d

การกระจาย Return ในอดีต ไม่รับประกันความเสี่ยงอนาคต

ขยายข้อ 07 · แยก Supply เชิงโครงสร้าง, Liquidity ที่แสดง และ Activity ที่เกิดการซื้อขายแล้ว

หุ้นมี “Supply” หลายความหมาย Shares Outstanding คือหน่วยความเป็นเจ้าของที่ออกแล้ว Free Float ประมาณหุ้นที่หมุนเวียนซื้อขายได้มากกว่า Ask Book แสดงคำสั่งขายที่เปิดเผยในขณะนั้น ส่วน Executed Volume เก็บเฉพาะรายการที่จับคู่แล้ว ทั้งหมดควรอยู่คนละ fact table และคนละ time grain

STRUCTURAL SUPPLY

Shares และ Free Float

เก็บ effective_from/effective_to ของ shares outstanding และ float พร้อมปรับ denominator ในอดีตเมื่อเกิด split, reverse split, rights, buyback และการออกหุ้นใหม่

  • turnover = adjusted_volume / effective_free_float
  • ห้ามนำ Volume วันนี้หารด้วยจำนวนหุ้นจากอนาคตหรือค่าที่เก่าเกินไป
DISPLAYED LIQUIDITY

Bid, Ask, Depth และ Spread

Feature จาก Order Book ต้องมี venue, sequence number และ event time คำสั่งอาจถูกยกเลิกหรือซ่อน Displayed Depth จึงเป็นเจตนาที่สังเกตได้ ไม่ใช่ Demand ที่รับประกัน

  • mid = (best_ask + best_bid) / 2
  • relative_spread = (best_ask − best_bid) / mid
EXECUTED ACTIVITY

Trade และ Volume

Trade แสดงว่าผู้ซื้อและผู้ขายจับคู่กันแล้ว แต่ไม่เปิดเผยเจตนาที่ไม่ได้ execute ทั้งหมด ควร Aggregate ตาม instrument–venue–interval ก่อนเปรียบเทียบตลาด

  • VWAP = Σ(price × quantity) / Σ(quantity)
  • trade_intensity = trades / active_seconds
RISK CONTEXT

Return และ Realized Volatility

ใช้ราคาที่ปรับ corporate action และกำหนด return interval ให้ชัด ช่วงข้อมูลหาย ตลาดปิด และการซื้อขายบางทำให้ความหมายของ volatility เปลี่ยน

  • r_t = ln(P_t / P_t−1)
  • realized_volatility = sqrt(Σ r_t²)

ตัวอย่างคำนวณ Order-book Snapshot

best_bid = 101.50, bid_size = 4,300 best_ask = 102.00, ask_size = 3,100 mid = (101.50 + 102.00) / 2 = 101.75 relative_spread = 0.50 / 101.75 = 0.4914% book_imbalance_l1 = (4,300 - 3,100) / (4,300 + 3,100) = 0.1622 ความหมาย: ขณะนี้ขนาดที่แสดงใน L1 เอนมาทาง Bid แต่ไม่ได้พิสูจน์ว่าราคาต้องขึ้น เพราะคำสั่งอาจถูกยกเลิก มี Hidden Liquidity และระดับลึกกว่านี้อาจให้ภาพตรงข้าม
คีย์แบบ POINT-IN-TIMEinstrument + venue + event_time + sequence
คีย์ CORPORATE ACTIONinstrument + effective_from + adjustment_version
การป้องกันในโมเดลAlign ทุก Feature กับข้อมูลที่สังเกตได้ก่อน prediction time

08 · OTHER FINANCIAL PATTERNS

สถาปัตยกรรม OLAP เดียวกันรองรับคำถามการเงินได้หลายประเภท

ตัวอย่างนี้เป็น Data Product และ Feature ไม่ใช่การพยากรณ์กำไรหรือคำแนะนำลงทุน

FX & TREASURY net_exposure_7d · basis_change · cash_gap
CREDIT utilization_3m · payment_ratio · missed_count_12m
PORTFOLIO & RISK sector_weight · duration · concentration · drawdown
FRAUD & AML velocity_1h · new_device_7d · circular_flow_score
INSURANCE claim_frequency · loss_ratio · reporting_delay
MACRO DATA surprise_vs_consensus · revision_size · trend_3m

09 · SQL EXAMPLE: DAILY MARKET FEATURES

Materialize Window หลังประกาศกฎ Adjustment และ Availability

ข้อมูลจริงต่างกันตาม Venue, License, Session, Corporate-action Convention และ Timestamp Precision

WITH daily AS (
 SELECT instrument_key, trading_date,
        MAX(adjusted_close) AS close,
        SUM(volume) AS volume,
        AVG((ask-bid)/NULLIF((ask+bid)/2,0)) AS relative_spread
 FROM analytics.fact_market_observation
 WHERE available_at <= trading_date + INTERVAL '1 day'
 GROUP BY instrument_key, trading_date
), returns AS (
 SELECT *, LN(close/NULLIF(LAG(close) OVER
   (PARTITION BY instrument_key ORDER BY trading_date),0)) AS return_1d
 FROM daily
)
SELECT instrument_key, trading_date AS feature_date,
       volume, relative_spread, return_1d,
       AVG(volume) OVER (PARTITION BY instrument_key ORDER BY trading_date
         ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS avg_volume_20obs,
       STDDEV_SAMP(return_1d) OVER (PARTITION BY instrument_key ORDER BY trading_date
         ROWS BETWEEN 19 PRECEDING AND CURRENT ROW) AS volatility_20obs
FROM returns;
ก่อนเผยแพร่

ต้องกำหนด Adjustment, Holiday, Missing Price, Listing, Delisting, Session, Revision และ Licensing เพราะ SQL ที่รันถูกยังสร้าง Data Product ที่ผิดได้

03 · BUILD A FEATURE SPINE

เริ่มจากนิยามแถวที่อนุญาตให้โมเดลเรียนรู้

Entity Spine ยึดหนึ่ง entity ไว้กับหนึ่ง prediction time ทุก Feature ต้อง join เข้ากับแถวนั้นโดยไม่ใช้ข้อมูลที่มาถึงภายหลัง

ENTITY SPINE
customer_idprediction_timelabel_time
1012026-08-01 09:002026-08-08
1012026-08-15 09:002026-08-22
+
ELIGIBLE HISTORY
t − 90dfeature windowtlabel window
FEATURE VECTOR[orders_30d,
spend_90d,
days_since_last_order,
segment_v3]
สัญญาของหนึ่งแถวEntity + prediction time + feature version กำหนด observation ส่วน label time อยู่หลัง prediction time และห้ามรั่วเข้า Feature

04 · FEATURE ENGINEERING LAYERS

แยกหลักฐานที่ใช้ซ้ำได้ออกจากการตีความเฉพาะโมเดล

ไม่ควรใส่ทุก transformation ไว้ใน Feature Query ขนาดใหญ่เพียงชุดเดียว การแบ่งชั้นทำให้เห็น ownership, testing, reuse และต้นทุน

1RAW / BRONZE

รักษาหลักฐานต้นทาง

Event ที่ไม่แก้ไขหรือ replay ได้ พร้อม source timestamp และ ingestion metadata

2CLEAN / SILVER

ปรับ representation

ชนิดข้อมูล deduplication, key, นโยบายข้อมูลมาช้า และ quality flag

3BUSINESS / GOLD

เผยแพร่ความหมายเชิงวิเคราะห์

Fact, dimension, entity-day aggregate และกฎธุรกิจที่ review แล้ว

4FEATURE

คำนวณหลักฐานของโมเดล

Point-in-time window, encoding, default และ Feature Version

5STORAGE

Materialize เพื่อการเข้าถึง

Historical offline row, batch snapshot และค่าล่าสุดแบบ online

05 · SQL LAB: MATERIALIZE FEATURES

ย้ายการคำนวณราคาแพงจากทุกครั้งที่อ่าน มาไว้ใน Build ที่ควบคุมได้

ตารางที่ build แบบ incremental เป็นรูปแบบหนึ่งของ Offline Feature Store ส่วน syntax จริงขึ้นกับ Warehouse หรือ Lakehouse ที่ใช้

CREATE TABLE IF NOT EXISTS features.customer_activity_daily (
  customer_id        BIGINT NOT NULL,
  feature_date       DATE NOT NULL,
  orders_30d         INTEGER NOT NULL,
  spend_30d          DECIMAL(14,2) NOT NULL,
  days_since_order   INTEGER,
  feature_version    VARCHAR(30) NOT NULL,
  computed_at        TIMESTAMP NOT NULL,
  PRIMARY KEY (customer_id, feature_date, feature_version)
);

-- Build only the affected feature_date partition.
INSERT INTO features.customer_activity_daily
SELECT
  c.customer_id,
  :feature_date,
  COUNT(o.order_id),
  COALESCE(SUM(o.net_amount), 0),
  DATE_PART('day', :feature_date - MAX(o.order_date)),
  'customer_activity_v1',
  CURRENT_TIMESTAMP
FROM analytics.dim_customer c
LEFT JOIN analytics.fact_order o
  ON o.customer_id = c.customer_id
 AND o.order_date >= :feature_date - INTERVAL '30 days'
 AND o.order_date <  :feature_date
 AND o.is_completed = TRUE
GROUP BY c.customer_id
ON CONFLICT (customer_id, feature_date, feature_version)
DO UPDATE SET
  orders_30d=EXCLUDED.orders_30d,
  spend_30d=EXCLUDED.spend_30d,
  days_since_order=EXCLUDED.days_since_order,
  computed_at=EXCLUDED.computed_at;
ทำไมต้องเก็บ feature_date

หากไม่มีเวลา observation ค่า spend_30d จะสร้างซ้ำหรือเปรียบเทียบไม่ได้ การเก็บเฉพาะค่าล่าสุดอาจรองรับ online prediction แต่สร้าง historical training set ซ้ำไม่ได้

06 · WHY MATERIALIZED FEATURES CAN OUTRUN A VIEW

คำนวณครั้งเดียว อ่านหลายครั้ง เมื่อ workload นั้นเกิดซ้ำจริง

VIEW ปกติโดยทั่วไปเก็บ SQL ไม่ได้เก็บผลลัพธ์ ทุก query จึงอาจทำ join, filter, window และ aggregation ซ้ำ ส่วน Materialized Feature Table จ่ายต้นทุนตอน Build ทำให้การอ่านภายหลังแคบและคาดการณ์ได้มากกว่า

LOGICAL VIEW · COMPUTE ON READ
request 1
scan + join + window + aggregate
result
request 2
scan + join + window + aggregate
result
MATERIALIZED FEATURE · COMPUTE ON WRITE
scheduled / incremental build
stored feature rows
partitioned · indexed · compact
↗ request 1→ request 2↘ request 3
ภาพที่ 2 Materialization ลดการคำนวณซ้ำและความแปรปรวนของ latency ได้ โดยแลกกับ storage, build time, orchestration และการจัดการ freshness
มิติLogical VIEWMaterialized Feature TableOnline Feature Store
งานต่อการอ่านอาจรันแผนเต็มซ้ำกรอง/เลือกแถวที่เก็บแล้วค้นด้วย key
เป้าหมายทั่วไปAbstraction ที่สดTraining และ batch throughputLatency ต่ำที่คาดการณ์ได้
ความสดอ่าน source ปัจจุบันณ Build ล่าสุดที่สำเร็จณ Sync/Update ล่าสุด
ต้นทุนหลักCompute ซ้ำStorage + Build + BackfillPlatform + Sync + Availability
เหมาะเมื่อLogic เบาหรืออ่านไม่บ่อยFeature แพงและใช้ซ้ำPrediction มี latency เข้มงวด
ข้อสรุปเรื่องความเร็วที่ควรพูดให้แม่น

Materialized Feature อาจเร็วกว่า Logical VIEW ที่ซับซ้อนมาก เมื่อหลีกเลี่ยง scan และ join ซ้ำ แบ่ง partition ตรงกับรูปแบบการอ่าน และมีขนาดเหมาะสม แต่ไม่ได้เร็วกว่าเสมอ Database อาจ optimize หรือ cache VIEW ง่าย ๆ ได้ดี ตาราง materialized อาจเก่าหรือจัด cluster ไม่เหมาะ และการ Build Feature ที่ไม่มีผู้ใช้ยิ่งเปลืองกว่าสิ่งที่ประหยัดได้ ต้อง benchmark ด้วย query, ปริมาณข้อมูล, concurrency และ freshness target จริง

07 · PERFORMANCE LEVERS

การออกแบบ Storage กำหนดว่า Materialization จะคุ้มหรือไม่

การคำนวณล่วงหน้าเพียงอย่างเดียวยังไม่ใช่สถาปัตยกรรม ผลลัพธ์ที่เก็บต้องสอดคล้องกับเส้นทางการเข้าถึงและข้อจำกัดเชิงปฏิบัติ

01

Partition pruning

แบ่ง Historical Feature ด้วย feature_date หรือขอบเขตเวลาหลัก เพื่อให้ training ข้ามประวัติศาสตร์ที่ไม่เกี่ยวข้อง

02

Clustering / sorting

จัดแถวตาม entity และเวลา เพื่อลด block ที่ต้องอ่านใน point-in-time retrieval

03

Columnar projection

อ่านเฉพาะคอลัมน์ Feature ที่ใช้ หลีกเลี่ยงตารางกว้างมากเมื่อแต่ละโมเดลใช้คนละกลุ่ม Feature

04

Incremental build

คำนวณเฉพาะวันที่และ entity ที่กระทบแทนทั้งประวัติศาสตร์ พร้อมนิยามว่าข้อมูลมาช้าเปิด partition เก่าอย่างไร

05

Pre-aggregation

เก็บ customer-day หรือ entity-hour ขั้นกลาง เพื่อให้ rolling window หลายชุดใช้ input ที่เล็กลงร่วมกัน

06

Key-value serving

สำหรับ online inference ให้ materialize เฉพาะ vector ล่าสุดที่อนุมัติ keyed ด้วย entity พร้อม atomic update และ TTL เมื่อเหมาะสม

07

Cache deliberately

Cache ช่วยการอ่านซ้ำที่ร้อน แต่ต้องมี invalidation, capacity และ correctness rule และไม่แทน Historical Storage

08

Compact files

หลีกเลี่ยงไฟล์เล็กจำนวนมากใน Lakehouse การ compaction ช่วย metadata และประสิทธิภาพ scan

08 · STORE EACH FEATURE ON PURPOSE

Feature หนึ่งตัวอาจมีหลาย Physical Representation

นิยามควรยังเป็น concept เดียวที่กำกับดูแลได้ แม้ History, Batch Snapshot และ Online Value ใช้ Storage Engine ต่างกัน

HISTORICAL OFFLINE

entity × observation_time

ประวัติศาสตร์แบบ point-in-time สำหรับ training, evaluation, audit และ backfill

customer_id, feature_date, value, version
BATCH SNAPSHOT

entity × scoring_run

Input ที่ freeze สำหรับ campaign หรือ scoring run หนึ่งรอบ ช่วย reproducibility

run_id, customer_id, feature_vector
ONLINE LATEST

entity → latest vector

Lookup ขนาดเล็ก latency ต่ำสำหรับ prediction request ส่วนประวัติศาสตร์ยังอยู่ offline

customer_id → {features, timestamp, version}

09 · QUALITY, FRESHNESS AND COST

Feature ที่ผิดแต่เร็ว คือ Incident ที่มาถึงเร็วขึ้น

Materialization สร้าง data product ที่มี state ใหม่ จึงต้อง monitor จริงจังพอ ๆ กับ source และ model

CorrectnessUniqueness · Null Policy · Range · Reconciliation · PIT Leakage Test
FreshnessSource Delay · Build Completion · Online Sync Age · พฤติกรรมเมื่อข้อมูลเก่า
Parityค่า Offline เทียบ Online · Code/Definition ร่วม · Sampled Comparison
PerformanceBuild Duration · Scan Bytes · Query p95/p99 · Online Lookup Latency
CostCompute ต่อ Build · Storage ต่อ Version · Backfill Cost · ค่าใช้จ่าย Feature ที่ไม่มีผู้ใช้
OperationsOwner · Lineage · Incident Runbook · Rollback · Deprecation Date

10 · DECISION GUIDE

Materialize เพราะมีหลักฐานว่าคุ้ม ไม่ใช่เพราะการเก็บไว้รู้สึกปลอดภัยกว่า

เลือก representation ที่เรียบง่ายที่สุดซึ่งยังตอบ correctness, reuse, freshness, latency และ recovery

KEEP AS VIEW

Logic เบา อ่านไม่บ่อย

ใช้เมื่อความสดสำคัญ แผน query มีประสิทธิภาพ และ compute ซ้ำมีต้นทุนต่ำ

MATERIALIZE OFFLINE

ประวัติศาสตร์แพงและใช้ซ้ำ

ใช้กับ training ที่สร้างซ้ำ heavy window, หลายโมเดล หรือ batch scoring ที่คงที่

ADD ONLINE STORE

Prediction มี latency เข้มงวด

ใช้เมื่อ request รอ Warehouse Compute ไม่ได้ และ Sync ค่าล่าสุดได้อย่างเชื่อถือ

PRE-AGGREGATE FIRST

มี Window ที่เกี่ยวข้องจำนวนมาก

สร้าง Entity-Time Summary ที่ใช้ซ้ำ ก่อนสร้าง Feature คล้ายกันนับร้อย

THE CENTRAL IDEA

OLAP ทำให้ประวัติศาสตร์คำนวณได้ ส่วน Feature Storage ทำให้ผลคำนวณที่เลือกแล้วใช้ซ้ำและเร็วขึ้น โดยแลกกับ State ที่ต้องดูแล