UPDATE flatSET city = 'Hull'WHERE ord = 1;UPDATE flatSET city = 'Leeds'WHERE ord = 1;INSERT INTO ordersVALUES (4, 'Cat');UPDATE customersSET city = 'Hull'WHERE cust = 'Ana';SELECT * FROM ordersNATURAL JOIN customersNATURAL JOIN itemsNATURAL JOIN products;ord cust city item price3 Ana mug,tea 8,41 Ana mug 8LeedsHull2 Ben York tea 43 Ana mug 8LeedsHull3 Ana tea 4LeedsHullcust cityAnaBen YorkLeedsHullord cust1 Ana2 Ben3 AnacityLeedsYorkLeedsord item1 mug2 tea3 mug3 teaitem pricemug 8tea 4ord cust cityitem priceord itemcust cityCat
Back: the SQL statement and the flat tableFront: customers, orders, items and productsChips: the columns that move; envelopes: statements and rowsAt the back: the SQL statement being run, and a small shop's one flat table of orders. In front: the four tables it is split into. Each cell first gets one value (1NF). Then each column moves to the table whose key decides it: price to products and cust to orders (2NF), and city to customers (3NF). Foreign keys link the tables; Ana's move to Hull becomes a one-row change, and a join rebuilds the original rows with nothing lost. Without ORDER BY, SQL does not promise any order for the rows of an answer. The figure shows them in order number order.

One big table

  1. A small shop keeps every order in one flat table: the order number, the customer, their city, the item and its price. Order 3 bought two things, so its cells hold lists: mug,tea and 8,4.

Split by dependency

The payoff

What happens

;; step 1/10 · flat
table flat (as the shop first keeps it)
  ord cust city  item    price
  1   Ana  Leeds mug     8
  2   Ben  York  tea     4
  3   Ana  Leeds mug,tea 8,4

order 3 crams two items into one cell,
and two prices into another.
to find who bought tea, every program must
split those lists itself.

Real tables give each customer a generated id as the key, because two customers can share a name. Names keep this example short. Stricter forms exist beyond 3NF: Boyce–Codd normal form (BCNF), 4NF and 5NF. Most designs aim for 3NF or BCNF; the four tables here already meet BCNF.