The Nesting Decision

A nested column holds a structure where a flat column holds a single value. An order row in a flat schema stores customer_id, order_date and total, 1 value per column. The same order in a nested schema can also carry items, a list of 3 records, each with a sku, a quantity and a price. The list sits inside the row, so reading the order reads its items without a join.

Order 1001 occupies 1 row in orders and 3 rows in order_items, linked by order_id. Splitting a repeating part into its own table like this, 1 row per item, is called normalizing. The embedded version keeps the same facts in 1 table:

order_idcustomer_idorder_dateitems
1001772026-09-14[{MUG-350, 2, 9.00}, {TEE-M, 1, 24.00}, {CAP-BLK, 1, 15.00}]
1002122026-09-14[{TEE-M, 3, 24.00}]

Both versions answer every question about these orders. They differ in what a row means and therefore in which queries are cheap. In the normalized version, a row of order_items means 1 item of 1 order, so counting how many times TEE-M sold is a filter and a sum over 1 table. In the embedded version, a row means 1 complete order, so loading an order for the checkout page is 1 row read, and counting TEE-M sales means opening every list.

Five questions that decide it

Run the Airbnb listing through those 5 questions. Amenities exist only for the listing, load with it, change with it, stay small and belong to 1 listing: embed. Reviews are written and edited on their own, grow without a ceiling and are read in bulk by the ratings pipeline: normalize. The host is shared across listings, so the listing stores a host_id and the host table holds the facts, with at most a display name copied in for the search card.

Embed when
  • The child has no meaning outside this parent
  • Parent and child are read together on the hot path
  • The list has a small, known ceiling
  • The child changes only when the parent changes
Normalize when
  • The child is shared by many parents
  • The child is queried in bulk across parents
  • The list grows without bound
  • The child is edited by a different process or team

A food delivery app models restaurants. Each restaurant has opening hours, menus, reviews and orders. Which of these belongs embedded in the restaurant row?

About this lesson

This section is part of the Nested Data lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.