# 1.2 The Physical Suitcase (The Tuple) ![The Tuple Suitcase](assets/arch_tuple_suitcase.png) In the **Elephant Cafe**, a **Tuple** is the absolute smallest unit of luggage. It’s not just a "row" of data; it’s a highly specific, slightly neurotic physical suitcase that carries everything a record needs to survive its journey through the database. It is critical to distinguish between the **Logical Row** and the **Physical Tuple**: - **The Tuple (Physical)**: This is the actual physical suitcase sitting on a conveyor belt. Because of the elephant's refusal to erase things (see [[Chapter 1/1.5 - The Sharpie Ledger (MVCC)|1.5 - The Art of the Sharpie]]), a single logical **Row** might actually be represented by dozens of physical **Tuples**—old versions, newer versions, and deleted versions. --- ## The Anatomy of a Suitcase If you were to unbuckle the leather straps and look inside a physical suitcase, you would see a very specific, ordered arrangement of bureaucratic paperwork and actual data. ### The Schematic ```text +---------------------------------+ <-- Suitcase Start | t_xmin (4 bytes) | (Who packed this?) +---------------------------------+ | t_xmax (4 bytes) | (Who threw this away?) +---------------------------------+ | t_cid (4 bytes) | (Which command?) +---------------------------------+ | t_ctid (6 bytes) | (Where is the next one?) +---------------------------------+ | t_infomask (2 bytes) | (Visibility bitflags) +---------------------------------+ | [ PADDING / ALIGN ] | (The Socks) +---------------------------------+ | NULL BITMAP (Optional) | (The Checklist) +---------------------------------+ | | | USER DATA | (The actual laundry) | [Slot 1] [Slot 2] ... | | | +---------------------------------+ <-- Suitcase End > [!NOTE] > Every **Slot** in the suitcase (Column) is a designated compartment. The elephant uses the **Blueprint** to calculate exactly where each compartment starts, ensuring he never confuses a scarf for a shirt. ``` --- ## 1. The Header (`HeapTupleHeaderData`) Living in the front pocket of every suitcase is a slightly stressed **Bureaucratic Bird** (the Header). Under the hood, this is literally the C-struct `HeapTupleHeaderData` defined in the Postgres engine. This 23-byte fixed-size structure is the "passport" of the tuple. It tells the system who created it, who deleted it, and whether it’s even legal to look at it without a formal invitation to a tea party. | Field | Size | Metaphor | Technical Description | | :----------- | :------ | :------------------- | :-------------------------------------------------------------------- | | `t_xmin` | 4 bytes | **Creation Stamp** | The Transaction ID (XID) that inserted this tuple. | | `t_xmax` | 4 bytes | **Deletion Stamp** | The Transaction ID that deleted or locked this tuple. | | `t_cid` | 4 bytes | **Command ID** | The specific command within the transaction that acted on it. | | `t_ctid` | 6 bytes | **Location Tag** | The physical address (Page #, Offset) of this tuple or its successor. | | `t_infomask` | 2 bytes | **Visibility Flags** | Bitflags describing the tuple's state (commits, aborts, has nulls). | > [!NOTE] > The `t_ctid` is the physical "GPS coordinate" of the suitcase defined as `(blockNumber, offsetNumber)`. If a row is updated, the old tuple’s `t_ctid` is updated to point to the new physical location of the next version. It’s like a trail of breadcrumbs, but the birds are too busy with paperwork to eat them! ### The Ghost Items (System Columns) Because of the Bird's meticulous record-keeping, every single tuple you create is secretly carrying extra "ghost" items you never asked for. Even if your table only has one column `(name text)`, the elephant quietly packs several **System Columns** into the suitcase. If you ever want to see these hidden passengers, you can explicitly ask the elephant for them in your query. Let's look at a specific animal in our cafe: ```sql -- Asking for the hidden passengers SELECT ctid, xmin, xmax, name FROM animals WHERE name = 'Babu'; ``` The elephant will return something like this: | ctid | xmin | xmax | name | | :---- | :--- | :--- | :--- | | (0,1) | 501 | 0 | Babu | * **`ctid (0,1)`**: This is the literal physical address in the depot: **Page 0, Offset 1**. * **`xmin 501`**: This is the ID of the transaction that "packed" this suitcase (inserted the row). * **`xmax 0`**: Since this is 0, it means nobody has "marked" this suitcase for deletion yet. It is a live, happy row! It’s a glimpse into the matrix! ## 2. The Null Bitmap (The Checklist) If your table has many columns that might be empty (NULL), the elephant doesn't want to waste suitcase space on them. Instead, it maintains a **Checklist** (the Null Bitmap) right after the header. If a bit is set to 0, the elephant knows that specific "Slot" wasn't packed, and he skips over it entirely when unpacking the suitcase. **NULLs in Postgres are essentially free**—they take up almost no physical space! ## 3. The Padding Socks (Alignment) Postgres prefers to pick up suitcases in 8-byte chunks. If your data (Header + Bitmap + User Data) doesn't end on an 8-byte boundary, the elephant stuffs **Padding Socks** (useless zero-bytes) into the corners. > [!WARNING] > This leads to **Column Tetris**. > A table with `(int, char(1), int)` takes up more space than `(int, int, char(1))` because the elephant adds padding socks to align the `int`s on 8-byte boundaries. Keep your large items together to save suitcase space! ## 4. TOAST (Oversized Attribute Storage) How curious! What if a single item is too big for the suitcase (usually > 2KB)? The elephant won't struggle with it. He won't push it, pull it, or try to fold it like a waistcoat. Instead, he ships the large item off to a **Separate Trailer** (the TOAST table) and leaves a tiny "Claim Check" in the suitcase. TOAST stands for **The Oversized-Attribute Storage Technique**, and it is the reason you can store multi-gigabyte "life story" strings without breaking the 8KB [[Structures/Page|Page]] limit. --- | [[Chapter 1/1.1 - Knicks, knacks, bits, and bobs (Data types)\|1.1 - Data Types]] | [[Learn You a Postgres for Great Good\|Home]] | [[Chapter 1/1.3 - The Shipping Container (The Page)\|1.3 The Shipping Container (The Page)]] |