A cell is one entry on a b-tree page: a row, an index entry, or a divider that points to a child page. The page type decides which of four layouts its cells use. Numbers marked varint use SQLite’s variable-length integers; the others are big-endian.
The four layouts
| Part, in order | Table leaf (13) | Table interior (5) | Index leaf (10) | Index interior (2) |
|---|---|---|---|---|
| Left child page, u32 | – | yes | – | yes |
| Payload size, varint: all of it, overflow included | yes | – | yes | yes |
| Rowid, varint | yes | yes (the key) | – | – |
| Payload: the part that stays on the page | yes | – | yes | yes |
| First overflow page, u32: only if the payload spills | yes | – | yes | yes |
The payload is a record. How much of it stays on the page, and when the rest goes to overflow pages, is set by the overflow thresholds. A reader learns whether a cell spills by comparing its payload size with them: no flag in the cell says so.
Table leaf cells
A row of a table: its rowid and its record.
| Size | Type | Name | Description |
|---|---|---|---|
| 1 to 9 | varint | Payload size | The size of the record in bytes, including any part on overflow pages. |
| 1 to 9 | varint | Rowid | The row’s 64-bit signed integer key. |
| varies | bytes | Payload | The record, or its first part if it spills. |
| 0 or 4 | u32 | First overflow page | Present only when the payload spills. |
Table interior cells
A divider. The left child page holds the rows whose rowids are less than or equal to this cell’s key; the next cell’s left child, or the page’s right-most pointer after the last cell, holds the larger ones. There is no payload, so these cells never spill.
| Size | Type | Name | Description |
|---|---|---|---|
| 4 | u32 | Left child page | The child page with the keys up to and including this one. |
| 1 to 9 | varint | Key | A rowid: every row under the left child has a rowid up to and including it. |
Index leaf cells
An index entry: a record of the indexed values followed by the row’s key, the rowid or, for a WITHOUT ROWID table, its PRIMARY KEY columns. See Indexes.
| Size | Type | Name | Description |
|---|---|---|---|
| 1 to 9 | varint | Payload size | The size of the record in bytes, including any part on overflow pages. |
| varies | bytes | Payload | The record, or its first part if it spills. |
| 0 or 4 | u32 | First overflow page | Present only when the payload spills. |
Index interior cells
An index entry that also points to the child page holding the smaller entries. In an index b-tree every entry appears exactly once, on a leaf page or on an interior page. Read in order, a child’s entries come before the interior cell that points to it, and the entries under the right-most pointer come after the last cell.
| Size | Type | Name | Description |
|---|---|---|---|
| 4 | u32 | Left child page | The child page with the entries before this one. |
| 1 to 9 | varint | Payload size | The size of the record in bytes, including any part on overflow pages. |
| varies | bytes | Payload | The record, or its first part if it spills. |
| 0 or 4 | u32 | First overflow page | Present only when the payload spills. |
A real cell
A table leaf cell from the files examined for this site, a row of a link table made
as (id INTEGER PRIMARY KEY, author, paper):
06 21 04 00 01 01 1B 0A
06: a payload of 6 bytes.21: rowid 33.- The payload is the record:
04, a record header of 4 bytes; serial types00(NULL),01and01(8-bit integers). - The values: NULL, then
1B= 27 and0A= 10.
The id column is an INTEGER PRIMARY KEY, so it is the rowid itself and is stored in the record as NULL. The row reads (33, 27, 10).