☰ Chapters
Week 10 · Denormalization
CT004-3.5-3 Advanced Database Systems · Week 10

Optimization Strategy: Denormalization

When and how to denormalize a relational schema for performance, and the trade-offs involved.

Contents
    Objectives

    Examples use the DreamHome case study (Connolly & Begg, Ch. 18).

    Why denormalize?

    Also consider that denormalization:

    What is denormalization?

    Definition

    Denormalization is a refinement to the relational schema such that the degree of normalization for a modified relation is less than the degree of at least one of the original relations.

    The term is also used more loosely for combining two relations into one new relation that is still normalized but contains more nulls than the originals.

    When to apply denormalization

    Consider it specifically to speed up frequent or critical transactions, in these situations:

    1. Combining 1:1 relationships
    2. Duplicating non-key attributes in 1:* relationships to reduce joins
    3. Duplicating foreign key attributes in 1:* relationships to reduce joins
    4. Introducing repeating groups
    5. Partitioning relations
    Extra · the golden rule

    Denormalize only after measuring a real performance problem on a critical transaction, and document it so that the redundant data is kept consistent (e.g. with triggers — Week 6).

    Sample relations (DreamHome)

    The relation diagram links: Client —Attends— Interview; Client —Requests— Viewing; PropertyForRent —Takes— Viewing; PrivateOwner —POwns— PropertyForRent; Branch —Offers— PropertyForRent; Branch —Provides— Telephone.

    PropertyForRent (normalized)
    propertyNostreetcitypostcodetyperoomsrentownerNostaffNobranchNo
    PA1416 HolheadAberdeenAB7 5SUHouse6650CO46SA9B007
    PL946 Argyll StLondonNW2Flat4400CO87SL41B005
    PG46 Lawrence StGlasgowG11 9QXFlat3350CO40B003
    PG362 Manor RdGlasgowG32 4QXFlat3375CO93SG37B003
    PG2118 Dale RdGlasgowG12House5600CO87SG37B003
    PG165 Novar DrGlasgowG12 9AXFlat4450CO93SG14B003
    PrivateOwner
    ownerNofNamelNameaddresstelNo
    CO46JoeKeogh2 Fergus Dr, Aberdeen AB2 7SX01224-861212
    CO87CarolFarrel6 Achray St, Glasgow G32 9DX0141-357-7419
    CO40TinaMurphy63 Well St, Glasgow G420141-943-1728
    CO93TonyShaw12 Park Pl, Glasgow G4 0QR0141-225-7025

    1. Combining 1:1 relationships

    Client and Interview have a 1:1 relationship (a client attends at most one interview). If they are frequently accessed together, combine them into one relation ClientInterview.

    Client
    clientNofNamelNamemaxRent
    CR76JohnKay425
    CR56AlineStewart350
    CR74MikeRitchie750
    CR62MaryTregear600
    Interview
    clientNostaffNodateInterviewcomment
    CR56SG3711-Apr-00current lease ends in June
    CR62SA97-Mar-00needs property urgently

    Combined:

    clientNofNamelNametelNoprefTypemaxRentstaffNodateInterviewcomment
    CR76JohnKay0207-774-5632Flat425
    CR56AlineStewart0141-848-1825Flat350SG3711-Apr-03current lease ends in June
    CR74MikeRitchie01475-392178House750
    CR62MaryTregear01224-196720Flat600SA97-Mar-03needs property urgently

    No join needed any more — but clients with no interview now have nulls in the interview columns. This is the “loose” form of denormalization (still normalized, more nulls).

    Trade-off

    Worth it only if the participation is fairly high (few nulls) and the two are almost always read together.

    2. Duplicating non-key attributes in 1:* relationships

    A frequent query lists properties with their owner’s last name:

    SELECT p.*, o.lName
    FROM   PropertyForRent p, PrivateOwner o
    WHERE  p.ownerNo = o.ownerNo AND branchNo = 'B003';

    If we duplicate lName from PrivateOwner into PropertyForRent, the join disappears:

    propertyNo…rentownerNolNamestaffNobranchNo
    PA14…650CO46KeoghSA9B007
    PL94…400CO87FarrelSL41B005
    PG4…350CO40MurphyB003
    PG36…375CO93ShawSG37B003
    PG21…600CO87FarrelSG37B003
    PG16…450CO93ShawSG14B003
    SELECT p.*
    FROM   PropertyForRent p
    WHERE  branchNo = 'B003';
    Cost

    If an owner’s last name changes, it must be updated in every property they own (e.g. Farrel appears twice) — an update anomaly reintroduced on purpose. Extra storage is also used.

    Special case: lookup tables

    Lookup (reference/code) tables hold a code and its description, e.g. PropertyType(type, description) with H = House, F = Flat, and PropertyForRent stores only the code:

    PropertyType
    typedescription
    HHouse
    FFlat

    Benefits of the lookup table: reduces the size of the child relation (a 1-char code instead of a description), makes changing a description easy (one row), and can be used to validate input.

    If the lookup table is used frequently or critically, and the description rarely changes, duplicate the description in the child relation so no join is needed:

    propertyNostreetcitytypedescriptionroomsrent
    PA1416 HolheadAberdeenHHouse6650
    PL946 Argyll StLondonFFlat4400
    PG46 Lawrence StGlasgowFFlat3350
    …………………

    Figure 18.5 — Modified PropertyForRent with duplicated description. The original lookup table can be kept for validation.

    3. Duplicating foreign key attributes in 1:* relationships

    Original: PrivateOwner —POwns→ PropertyForRent ←Offers— Branch. A frequent query: list all private owners at a branch:

    SELECT o.lName
    FROM   PropertyForRent p, PrivateOwner o
    WHERE  p.ownerNo = o.ownerNo AND branchNo = 'B003';

    Remove the join by duplicating the foreign key branchNo into PrivateOwner — i.e. introducing a direct relationship Branch —Serves→ PrivateOwner:

    SELECT o.lName
    FROM   PrivateOwner o
    WHERE  branchNo = 'B003';
    ownerNofNamelNameaddresstelNobranchNo
    CO46JoeKeogh2 Fergus Dr, Aberdeen AB2 7SX01224-861212B007
    CO87CarolFarrel6 Achray St, Glasgow G32 9DX0141-357-7419B003
    CO40TinaMurphy63 Well St, Glasgow G420141-943-1728B003
    CO93TonyShaw12 Park Pl, Glasgow G4 0QR0141-225-7025B003
    Assumption

    This only works if an owner rents properties through a single branch. If an owner could use many branches, you’d need a *:* relationship between Branch and PrivateOwner instead.

    From the lecture notes

    PropertyForRent holds branchNo because a property may not yet have a staff member. If it didn’t, the query would need two joins (via Staff):

    SELECT o.lName
    FROM   Staff s, PropertyForRent p, PrivateOwner o
    WHERE  s.staffNo = p.staffNo AND p.ownerNo = o.ownerNo
      AND  s.branchNo = 'B003';

    Removing two joins gives even greater justification for duplicating branchNo into PrivateOwner.

    4. Introducing repeating groups

    Repeating groups are removed during normalization (1NF) into a separate relation — e.g. a branch’s telephone numbers are held in Telephone(telNo, branchNo). If access to the phone numbers is critical, fold them back into Branch as separate columns:

    branchNostreetcitypostcodetelNo1telNo2telNo3
    B00522 Deer RdLondonSW1 4EH0207-886-12120207-886-13000207-886-4100
    B00716 Argyll StAberdeenAB2 3SU01224-67125
    B003163 Main StGlasgowG11 9QX0141-339-21780141-339-4439
    B00432 Manse RdBristolBS99 1NZ0117-916-1170
    B00256 Clover DrLondonNW10 6EU0208-963-1030

    telNo1 can be marked as an alternate key (AK). Consider this only when:

    5. Partitioning relations

    Rather than combining relations, decompose them into smaller, more manageable partitions. Two main types:

    Horizontal(rows)Vertical(columns)

    Horizontal partitioning

    Distributes the tuples (rows) across smaller relations.

    e.g. split PropertyForRent by type (Houses vs Flats), or split a sales table by year so queries on the current year scan less data.

    Vertical partitioning

    Distributes the attributes (columns) across smaller relations; the primary key is duplicated in each so the original can be rebuilt with a join.

    e.g. separate rarely-used large columns (photos, long descriptions) from frequently-used ones.

    Extra · why partition?

    Benefits: improved load balancing, better performance (smaller scans), higher availability (one partition can be offline), improved recovery, security (restrict access by partition). Costs: complexity, and queries across partitions are slower.

    Advantages and disadvantages

    AdvantagesDisadvantages
    Can improve performance by:
    • precomputing derived data;
    • minimizing the need for joins;
    • reducing the number of foreign keys in relations;
    • reducing the number of indexes (thereby saving storage space);
    • reducing the number of relations.
    • May speed up retrievals but can slow down updates.
    • Always application-specific and needs to be re-evaluated if the application changes.
    • Can increase the size of relations.
    • May simplify implementation in some cases but make it more complex in others.
    • Sacrifices flexibility.

    Table 18.1 — Advantages and disadvantages of denormalization.

    Quick review

    Define denormalization.
    Refining a relational schema so that the degree of normalization of a modified relation is lower than that of at least one original relation (also loosely: combining relations into one with more nulls).
    List the five denormalization situations.
    Combining 1:1 relationships; duplicating non-key attributes in 1:*; duplicating FK attributes in 1:*; introducing repeating groups; partitioning relations.
    When is introducing a repeating group acceptable?
    When the number of items is known, static, and small (typically ≤ 10).
    Horizontal vs vertical partitioning?
    Horizontal splits rows into separate relations; vertical splits columns (repeating the primary key in each part).
    Main disadvantage of denormalization?
    It speeds up reads but slows down (and complicates) updates, because redundant copies must be kept consistent; it also sacrifices flexibility.