Active Data Warehousing

Context: FIT3003_MOC Β· the warehouse that never stops loading β€” every rung of the granularity ladder kept current by views and triggers Β· when the design itself must change βž” Active Data Warehouse Evolution Parent Framework: Data Warehouse

Quick Revision

  • 🎯 Objective: an update to the operational database is immediately reflected in the warehouse βž” always up to date, no longer purely historical; exam payload = for each object choose view or table trigger, then trace one inserted row up every level.
  • πŸ“¦ Core Components: view βž” self-maintaining, no code (dimensions, measure-less facts, an upper fact that only re-aggregates a lower one) | table trigger βž” anything storing a value the source does not hold (a count, a derived band, a looked-up key).
  • ⚑ Key Constraint: bottom-up only βž” each level is maintained from the level immediately below, so the Level-1 trigger fires on the Level-0 fact, never on the operational table; break one link and every level above silently freezes.

πŸ“ How It Works

1. Passive vs active

  • Passive βž” once built, never changes: no insert, update or delete, so PK–FK constraints between fact and dimensions are unnecessary.
  • Active βž” dynamic: the source keeps writing into it, so PK–FK constraints become important to minimise anomalies from updates βž” dimension PKs via alter table … add constraint … primary key, fact FKs to every dimension, fact composite PK over all dimension keys.
  • Architecture βž” raw operational databases βž” one integrated operational database βž” Level-0 βž” Level-1 βž” Level-2, each arrow a build dependency.
  • Build direction βž” active is bottom-up (Level-0 first, each upper level on the one immediately below); passive may do the same but is often easier top-down (start at a reasonable Level-2, lower step by step) βž” Levels of Aggregation.
  • Incremental β‰  merely automatic βž” three concerns: automatic updates (Β§2), recentness of the data (Β§3), and changed rules (Β§4).
  • Scope βž” inserts only; update and delete are β€œdealt with separately”. Because the inter-dependencies are complex, active warehousing is used only where an application really needs active data.

2. Automatic updates β€” what each object becomes (Computer Lab case)

  • Dimension βž” create or replace view … as select distinct … over the operational table: new members appear with no code. Kept as a table βž” an after insert … for each row trigger on the source copies :new into it.
  • Level-0 fact without a measure βž” a view over Student LabActivities βž” no trigger.
  • Level-0 fact with Num_of_Logins βž” table trigger UpdateFactLevel0 on LabActivities: fetch the student’s DegreeCode with select … into, insert the row with measure .
  • Level-1 βž” Semester replaces Login Date, Time Period replaces Login Time βž” the TempFact is built from the Level-0 fact; trigger UpdateTempFactLevel1 on the Level-0 fact derives SemesterID and TimeID per row; the fact is count(StudentNo) over the TempFact; trigger UpdateFactLevel1 on the TempFact adds .
  • Level-2 βž” drops StudentDIM, reuses the rest βž” a view sum(Num_of_Logins) over the Level-1 fact: no TempFact, no trigger, always current.

3. Expiry date β€” recentness

  • Problem βž” Semester carries no Year, so Num_of_Logins accumulates every login ever made; old data has expired and should stop contributing.
  • Level-0 βž” table: add and to_char(LoginDate,'YYYY') >= '2015' to the build; view: the same filter in its where β€” it selects which source records enter the star.
  • Level-1 βž” trimming is a manual delete from TempComputerLabFactLevel1 where to_char(LoginDate,'YYYY') < '2015'; trigger ReduceFactLevel1 (after delete, reads :old) subtracts per deleted row.
  • Level-2 βž” a view βž” current as soon as Level-1 is.

4. Business rules changed β€” semester dates

  • Change βž” S1 moves from 1 Jan–15 Jul to 1 Jan–30 Jun (equal halves), effective 2021.
  • Level-0 βž” untouched: Semester first exists at Level-1.
  • Level-1 dimension βž” keep the rule’s history in a temporal dimension ; EndYear null marks the version in force βž” Slowly Changing Dimensions (SCD).
  • Level-1 TempFact βž” already built, so only its trigger changes: test year >= 2021 first, then band against 06/30, else the old 07/15.
  • Level-1 fact, its trigger, and Level-2 βž” unchanged: the fact only ever sees TempFact rows that arrive already banded, and Level-2 is a view.

πŸ—‚οΈ Schema

  • Level-1 dimensions βž” Β· β€” three periods: –, –, night.
flowchart BT
  LA[LabActivities] -->|UpdateFactLevel0| F0[ComputerLabFactLevel0]
  ST[Student] -.->|DegreeCode lookup| F0
  F0 -->|UpdateTempFactLevel1| T1[TempComputerLabFactLevel1]
  T1 -->|UpdateFactLevel1 +1 Β· ReduceFactLevel1 -1| F1[ComputerLabFactLevel1]
  F1 -->|view: sum| F2[ComputerLabFactLevel2]

βš™οΈ Core Implementation

πŸ”Ή Dimension β€” view, or table copy trigger

πŸ”Ή Level-0 fact with a measure

πŸ”Ή Level-1 TempFact banding trigger (with the 2021 rule)

πŸ”Ή Level-1 fact β€” find-or-insert on insert, decrement on delete

πŸ”Ή Level-2 β€” a view, nothing to maintain

βš–οΈ Core Decision Matrix

ObjectBuilt withMaintained byWhy
Dimension copied from a source tablecreate or replace viewnothing β€” re-run on readholds no value of its own
Dimension kept as a tablecreate table … as selectafter insert trigger on the sourcea physical table the fact’s FK can reference
Level-0 fact, no measureviewnothingrows distinct transactions
Level-0 fact, count measuretabletrigger on the transaction tablestores a measure and a looked-up key (DegreeCode)
Level-1 TempFacttable built from the Level-0 facttrigger on the Level-0 factstores derived bands (SemesterID, TimeID)
Level-1 facttablefind-or-insert trigger () after delete trigger () on the TempFactstores a running count
Level-2 factview over the Level-1 factnothingonly drops a dimension and re-sums

When It Flips: a view suffices exactly while the object is a pure query of something already current; the moment it stores a value computed at load time (a count, a band, a lookup) it becomes a table and owes a trigger.

πŸ“Š Exam Execution Trace & Applied Exercises

Manual Execution Trace β€” one login, every level

Student (BIT) logs in at on 4-Apr-2020; before the insert, Level-1 and Level-2 .

StepEventTrigger firedTable changedNew state
1insert into LabActivitiesUpdateFactLevel0Level-0 fact β€” DegreeCode from select into
2insert into Level-0 factUpdateTempFactLevel1Level-1 TempFact β€” ⟹ old rule, ⟹ S1; ⟹
3insert into TempFactUpdateFactLevel1Level-1 factIsFound ⟹
4β€”none (view)Level-2 factnext read:
5β€”none (views)LoginDateDim, LoginTimeDim4-Apr-2020 / visible if first seen
  • Reconciliation βž” the single source row adds exactly at every level; any level that moved by or has a broken or duplicated trigger.

⚠️ Common Mistakes

  • πŸ’‘ Firing an upper-level trigger on the operational table βž” bypasses the level below, so a filter or rule applied there (expiry, banding) is skipped and the levels drift apart.
  • πŸ’‘ Expiring by deleting from the fact βž” a Level-1 fact row is an aggregate with no LoginDate, so it cannot say which of its logins are old; trim the TempFact, which keeps the date, and let ReduceFactLevel1 propagate.
  • πŸ’‘ commit; inside the trigger bodies βž” every Chapter 18 trigger ends with one; write it that way in the exam, but a live Oracle run fails with ORA-04092 βž” Database Triggers (Oracle).

🧠 Active Recall