option1, option2, option3 instead of an options table
A normalised design would give each variant a set of named option values. Three fixed columns are blunt, but they turn the lookup for Large / Blue into a single indexed predicate rather than a group-by over a join, and three axes cover essentially every physical product. The cost is real: a fourth axis means a schema change, and the meaning of each slot lives in the product, not in the column name.