What You'll Master Here
Grain is the answer to "what does one row mean?" State it as "one row per ___" before you build anything.
If you remember one idea from this entire course, make it this one: the grain of a table is what a single row represents. It sounds almost too simple, and that is exactly why it is the most skipped and most expensive decision in data modeling.
Step through the three moves below. One solar dataset, three ordinary questions, three wrong answers — and not one of them raised an error. Breaking that silence is what this chapter is for.
Grain is the answer to "what does one row mean?" State it as "one row per ___" before you build anything.
Grain decides what every count and sum means. Get it wrong and there is no error message, just inflated, untrustworthy numbers that someone eventually makes a decision on.
- grain
- What a single row of a table represents (one order, one item, one day).
- atomic grain
- The lowest, most detailed level of a fact (one row per individual event).
- fan-out
- Row multiplication when joining a coarse-grain table to a finer-grain one.
- mixed grain
- A single table whose rows represent different things; a design error.
A solar operator asks: “how many inverters are reporting?”
| inverter_id | read_at | kwh |
|---|---|---|
| A-1 | 09:00 | 12 |
| A-1 | 09:05 | 11 |
| A-2 | 09:00 | 9 |
| A-2 | 09:05 | 10 |
| B-1 | 09:00 | 6 |
| B-1 | 09:05 | 5 |
- State what one row is
- One meaning per table
- Join without inflating
Building a table without saying its grain out loud first. You discover the grain only when a metric looks wrong, after code and dashboards already depend on it.
Write "one row per ___" before creating any table.
Confirm what count(*) means before trusting it.
Suspect grain first whenever a number looks too high.
Almost every "the numbers are wrong" incident is a grain problem in disguise: counting or summing at a grain different from what the question assumed.
Grain is what one row means; naming it explicitly before building is the single highest-leverage habit in data modeling.
