{
  "id": 5596414,
  "title": "Normalize It, Then Break It On Purpose: 3NF to Star Schema, Explained Through Food Delivery",
  "url": "https://urgent.news/2026/09/04/normalize-it-then-break-it-on-purpose-3nf-to-star-schema-explained",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-04T16:37:43.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/nbaubek/normalize-it-then-break-it-on-purpose-3nf-to-star-schema-explained-through-food-delivery-kp7"
  },
  "original_language": "en",
  "account": "Curb Appetite is a food delivery app that generates data as customers order from local restaurants and drivers pick up and deliver the orders. The starting point is a flat export table with columns for order_id, customer information, restaurant details, driver details, and items ordered along with their total cost. This table suffers from multiple issues that violate database normalization rules.\n\nThe first violation is found in the items_ordered column, which contains repeated groups of menu items. This column fails to meet the requirements of First Normal Form (1NF), which demands that every column hold a single atomic value and each row be uniquely identifiable. To resolve this, the data is split into a new table called order_items, with each row representing a single item ordered, containing order_id, menu_item_id, item_name, item_price, and quantity. This ensures all values are atomic and the question of how many Pad Thais were sold can now be answered by summing the quantity for that item.\n\nThe second violation occurs in the order_items table, which has a composite primary key (order_id, menu_item_id). This table needs to be in Second Normal Form (2NF), which requires that every non-key column depend on the entire primary key and not just part of it. In this case, item_name and item_price depend only on menu_item_id, not order_id. To fix this, menu_items and order_items tables are created, with menu_items containing information about each menu item and order_items referencing menu_items and storing the quantity of items ordered.\n\nFinally, the third violation is transitive dependencies in the orders table, where non-key columns depend on other non-key columns instead of directly on the primary key. In this example, customer_city and customer_state depend on the customer's zip code, which is not a direct dependency on the order_id. To resolve this, a new table for customers can be created, containing customer information and a reference to the order_id. This normalization process turns the original table into a properly normalized schema, with separate tables for order_items, menu_items, and customers, making it easier to answer business questions efficiently.",
  "summary": "Every data engineer eventually runs into the same apparent contradiction: the database design that every textbook, every senior review, and every \"how do I avoid duplicate data\" instinct insists is correct turns out to be the wrong shape the moment someone asks a real business question about it. That's not a contradiction. It's two different jobs sharing one word — \"database\" — when they actually…",
  "key_points": [
    "Original table violates 1NF due to repeated groups in itemsordered column",
    "Second violation: orderitems table needs 2NF with composite primary key",
    "Third violation: transitive dependencies in orders table, resolved with customers table"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}