Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/explanation/entity-integrity.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,30 @@ The rule applies whether the table has only new attributes or also inherits
attributes through foreign keys. A new primary-key attribute means a new
dimension.

### Grain

A dimension is a *single* axis of variation; a table's **grain** is the *whole
combination* of axes at which each row is recorded or computed — its full primary
key. Grain is the answer to this guide's leading question, *"what is one row of
this table?"*

> **The grain of a table is the level of detail at which its data is recorded or
> computed: what one row represents, given by the combination of dimensions in its
> primary key.**

- `Session`, keyed `(subject_id, session_idx)`, has grain **(subject × session)** —
one row per session of a subject.
- Adding a dimension makes the grain **finer**: a part table that adds `blob_idx`
(`Detection.Blob` below) has grain **(… × blob)** — one row per blob of a
detection.
- A computed table's grain is the combination of dimensions at which its `make()`
produces rows — its
[`key_source`](../reference/specs/autopopulate.md). *A computation operates at
its grain.*

"Grain" is the established term in dimensional modeling for what a single row
represents; DataJoint generalizes it from recorded fact rows to *computed* rows.

### Tables that introduce dimensions

```python
Expand Down
2 changes: 2 additions & 0 deletions src/reference/specs/autopopulate.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ class Analysis(dj.Computed):

The `key_source` property defines which entries should exist in the table—the complete set of primary keys that `make()` should be called with.

This set is the table's **grain**—the combination of dimensions at which the computation is done. `make()` runs once per key, so a computed table operates at the grain of its `key_source`.

### 2.2 Automatic Key Source

By default, DataJoint automatically calculates `key_source` as the join of all tables referenced by foreign keys in the primary key:
Expand Down
2 changes: 2 additions & 0 deletions src/reference/specs/query-algebra.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ result = A.aggr(B, ..., exclude_nonmatching=True) # Only rows with matches

**B must contain all primary key attributes of A.** This enables grouping B's rows by A's primary key.

Geometrically, aggregation **reduces the grain**: it projects the finer grain of `B` onto the coarser grain of `A` it contains, folding each group of B-rows into summary values. Requiring `B` to contain all of A's primary key is exactly what makes every B-row fall into one A-group. Note that `.proj` does *not* reduce the grain—it always retains the primary key (§3.2)—so aggregation, not projection, is the grain-reducing operator.

### 5.4 Aggregate Functions

```python
Expand Down
Loading