Fact Tables and Grain

A fact table stores one row per measurement event, and its grain states what one row means: "one row per order line" is a grain, "sales data" is not. Choose the most atomic grain the source offers: lines can always be summed into orders, never the reverse. Kimball names three kinds of fact table, plus the factless fact table that records an event with no measure (a customer viewed a book page):

Fact table types with BookNest examples
Type One row per BookNest example
Transaction Event, when it happens Order line sold
Periodic snapshot Entity per period Customers on file per quarter
Accumulating snapshot Process instance, updated as it moves Order from paid to delivered

The classic grain mistake is mixing levels. A coupon discount belongs to the whole order: copied onto every line, sum(discount) counts it once per line. Allocate it to lines in proportion to gross, or keep it in an order-grain fact table, as mart.sales did by leaving the net total on orders.