π― Objective: consolidate several low-cardinality, mutually unrelated dimensions into one dimension table β the junk dimension is the Cartesian product of their members, keyed by a single JunkID.
β‘ Key Constraint:low cardinality and unrelated are both required β a combined key (SemesterID= year β₯ semester) or a hierarchy (city β country) is not a junk dimension.
π How It Works
1. The Real-Estate case
Source β one large Property table; four of its columns are yes/no or four-valued: Ensuite, Pool, Spa, Aspect_Facing (East/North/South/West).
Measures β Num_of_Property and Total_Price; the analysis question is βhow many properties have a pool and a spaβ, βwhich face northβ.
Option 1 β non-junk β four separate dimensions βPropertyFACT1(EnsuiteIDβ,PoolIDβ,Aspect_FacingIDβ,SpaIDββ,Num_of_Property,Total_Price) β five tables in the star.
Option 2 β junk β one dimension βPropertyFACT2(JunkIDββ,Num_of_Property,Total_Price) β two tables in the star, and the fact still holds 32 rows.
Bound on size β the junk dimensionβs row count is never more than the factβs row count, because it is only the combinations that the fact can key on.
2. What is not a junk dimension
A combined key β SemYearDIM(SemesterID, Semester, Year) where SemesterID=201701 is just year β₯ semester made unique; the alternative is to split it into SemesterDIM and YearDIM, not to call it junk.
A hierarchy β CampusDIM(CampusID, β¦, CityName, State, Postcode, Country) splits into a city β country hierarchy (a snowflake) or into two independent dimensions β the attributes are related, so consolidating them is normal modelling.
The discriminator β junk needs many members, each cheap and no relationship between the attributes; both counter-examples fail the second test.
βοΈ Core Implementation
πΉ Option 1 β the non-junk build (four dimensions)
select distinct per column, then one update per member value
create table EnsuiteDim as select distinct Ensuite from Property order by Ensuite;alter table EnsuiteDim add (EnsuiteID number(1));update EnsuiteDim set EnsuiteID = 1 where Ensuite = 'no';update EnsuiteDim set EnsuiteID = 2 where Ensuite = 'yes';-- identical shape for PoolDim, SpaDim, AspectFacingDim (4 updates: East=1, North=2, South=3, West=4)create table PropertyTempFact1 asselect Ensuite, Pool, Aspect_Facing, Spa, Houseprice from Property;alter table PropertyTempFact1 add (EnsuiteID number(1)); -- + PoolID, Aspect_FacingID, SpaIDupdate PropertyTempFact1 set EnsuiteID = 1 where Ensuite = 'no';update PropertyTempFact1 set EnsuiteID = 2 where Ensuite = 'yes';create table PropertyFact1 asselect EnsuiteID, PoolID, Aspect_FacingID, SpaID, count(*) as Num_of_Property, sum(Houseprice) as Total_Pricefrom PropertyTempFact1group by EnsuiteID, PoolID, Aspect_FacingID, SpaID;
π‘ Common Mistake:Filling the IDs only in the dimensions β the temp fact needs its own alter add+update pass, or the final group by has nothing to group on.
πΉ Option 2 β the junk build (one dimension, sequence-keyed)
Cartesian product by select distinct, nextval for the key, correlated update for the fact
create table JunkDim asselect distinct Ensuite, Pool, Aspect_Facing, Spa from Propertyorder by Ensuite, Pool, Aspect_Facing, Spa; -- 32 combinationsalter table JunkDim add (JunkID number(2));drop sequence Seq_ID;create sequence Seq_ID start with 1 increment by 1 maxvalue 99999999 minvalue 1 nocycle;update JunkDim set JunkID = Seq_ID.nextval; -- one statement keys all 32 rowscreate table PropertyTempFact2 asselect Ensuite, Pool, Aspect_Facing, Spa, Houseprice from Property;alter table PropertyTempFact2 add (JunkID number(2));update PropertyTempFact2 TF set TF.JunkID = -- fill in a loop, without a cursor (select J.JunkID from JunkDim J where J.Ensuite = TF.Ensuite and J.Pool = TF.Pool and J.Aspect_Facing = TF.Aspect_Facing and J.Spa = TF.Spa);create table PropertyFact2 asselect JunkID, count(*) as Num_of_Property, sum(Houseprice) as Total_Pricefrom PropertyTempFact2 group by JunkID;
π‘ Common Mistake:Writing 32 hand-typed update β¦ set JunkID = n where <4 predicates> statements β that is the βupdate one-by-oneβ route the chapter shows first; the correlated subquery (or a PL/SQL cursor loop over JunkDim) does the same job once and does not rot when a member is added.
select * from the fact alone, or fact +JunkDim for the labels
Adding an attribute later
a new dimension and a new FK in the fact
rebuild JunkDim β every JunkID is renumbered
Readability of the fact
keys are self-describing
JunkID = 17 means nothing without the join
When It Flips: consolidate as soon as the attributes are unrelated and their cardinalities are small enough that βiββ£Dimiββ£ stays comfortably below the fact's row count. If any one dimension is large, or two of them are related, the product explodes or the model lies β keep them separate.
π§ Active Recall
The junk dimension holds the same 32 combinations the four separate dimensions could produce. What has actually been gained?
Answer
Short answer: the star becomes two tables instead of five, and every query loses nβ1 joins.
Why:The star is simpler β four spokes each carrying one yes/no column contribute no analytical structure, only diagram noise. The query is less complex β the nested βwhich features has the most expensive propertyβ question drops from five tables and four join conditions to a single select * against the fact. Nothing is lost β the combinations are the same set; only their addressing changed from four keys to one.
SemYearDIM(SemesterID, Semester, Year) merges two columns under one identifier. Why is that not a junk dimension?
Answer
Short answer: because Semester and Year are related β SemesterID is their concatenation acting as a unique identifier, not a Cartesian product of unrelated flags.
Why:Junk requires independence β Pool and Aspect_Facing say nothing about each other, so enumerating every pair is meaningful; a semester belongs to a year. The correct remedy differs β a combined dimension is split into SemesterDIM and YearDIM, or kept as a hierarchy when the relationship is many-1 (city β country in CampusDIM). Same surface, opposite move β junk consolidates, a combined dimension decomposes.