ContentsThe library

Designing a Table to Live With

Seventy-Eight Copies and No Tiebreaker

Last timeWhat One Row Means

Three failures follow from storing one fact twice, and all three are derivable rather than memorable. Normal form is the name for the repair, not a rule to obey.

The previous lesson split a table because its sentence had two subjects in it.

This lesson is the argument for why that mattered, and the argument is three

specific failures that can be derived from the duplication rather than taken on

authority.

Correcting it in every place

Start with the merged table. Every order row carries the region of the customer

who placed it, so a customer with three hundred orders has three hundred copies

of their region.

FIG 1One customer moves to a different region
stepstepwhat happenedrows carrying the old regionstate of the tablewhat happened
11customer 4471 moves from north to west312consistent and now wrongThe world has changed and the table has not. Every one of the 312 rows says north, which is at least an agreed answer even though it is the wrong one.
22an update runs over the order rows0consistent and rightIf it completes, all is well. The update touched 312 rows to record one fact about one customer, which is the cost of the duplication but not yet the danger.
33a second update runs with a date filter 46disagreeing with itselfThis is the real failure. The table now says north on 46 rows and west on 266, and no column anywhere records which of those is the current truth.
44a report groups orders by region46wrong, with no error raisedThe report runs, produces plausible numbers, and attributes 46 orders to the wrong region. Nothing in the system had an opinion about this.
55somebody tries to find the correct value46unanswerable from the dataAnd there is no way to tell from the table which answer is right. The only recoverable truth is outside the database, which is where this stopped being a storage problem.
5 steps
Five steps and the one worth staring at is the third. A stale table is merely wrong, and being uniformly wrong is recoverable because one correction fixes it. A table that disagrees with itself holds no information about which copy was right, so the repair requires going outside the database to find out. The duplication did not cause the missed update; it created the possibility that a missed update produces an inconsistency rather than a simple error.
FIG 2The chance that one of the copies goes wrong
the chance that any single row is missed or mis-updated
the number of rows carrying a copy of the fact
the chance that at least one copy ends up disagreeing with the others
The exponent is the duplication, which is why this is a design problem rather than an operations problem. At a per-row failure chance of two in a thousand, five rows is one chance in a hundred and four hundred rows is better than even. No amount of care brings the per-row figure to zero, so the only term available to work on is the one the schema controls.
FIG 3Risk against the number of copies
0.000.300.600.901.200.0125.0250.0375.0500.0rows carrying a copy of the same fact
a careful process, two failures per thousand rowsan ordinary process, one failure per hundred rows
Both curves start at zero and approach one, and the only question is how fast. The careful process buys a factor of five in the per-row rate and does not change the shape at all: it moves the point where failure becomes likely from about seventy copies to about three hundred and fifty. This is the honest argument against relying on discipline to manage duplication. Discipline shifts the curve along; removing the copies removes the curve.

The row that cannot exist

The second and third failures are quieter and they come from the same defect

seen from a different angle: a fact that can only be stored as a passenger on

another fact.

A customer who has not ordered anything yet has nowhere to live. There is no

customer row, only order rows, and the customer has no order. The usual

workaround is to insert an order row with the order fields left empty, which

means every query about orders now has to remember to exclude the ones that are

not orders, and the ones that forget are wrong by a small amount that nobody

notices.

And deleting the last order of a customer deletes the customer. Not as a

cascade anybody chose, but because the only place the customer existed was

inside that row. A tidy-up of orders older than seven years silently removes

every customer who has not ordered since, and the deletion is invisible because

no constraint was violated.

Both are the same thing. The customer fact has no independent existence, so it

appears when an order appears and vanishes when the last one goes.

The lesson stops here

3 more paragraphs to go

You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.

The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.

See the planThe contents

This is the reading half

Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.

The contents

The rest of this course

  1. 01Say Out Loud What One Row Is Claiming
  2. 02Seventy-Eight Copies and No Tiebreakeryou are here
  3. 03The Email Address Was Reused by the New Employeeopening only
  4. 04There Is No Column That Can Hold a Listopening only
  5. 05The Query Returned Nothing and the Query Was Correctopening only
  6. 06Copy the Value Only If You Are Also Building the Thing That Repairs Itopening only
  7. 07The Report Was Right in March and Is Wrong Nowopening only
  8. 08For Twenty Minutes, Both Versions Have to Be Rightopening only

Read alongside