# 1.1 The Tuple (The Physical Suitcase) ![The Tuple Suitcase](Postgres/assets/arch_tuple_suitcase.png) In the warehouse of the Lazy Elephant, 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 Row (Logical)**: This is the "ghost" or the "idea" of a record. When you say `SELECT * FROM users WHERE id=1`, you are asking for the _concept_ of that user. - **The Tuple (Physical)**: This is the actual physical suitcase sitting on a conveyor belt. Because of the elephant's refusal to erase things (see [[Postgres/Architecture/MVCC]]), a single logical **Row** might actually be represented by dozens of physical **Tuples**—old versions, newer versions, and deleted versions. --- ## 1. The Header (HeapTupleHeaderData) Living in the front pocket of every suitcase is a **Bureaucratic Bird** (the Header). 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. | 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. If a row is > updated, the old tuple’s `t_ctid` is updated to point to the new physical > location of the next version. ## 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 "item" wasn't packed, and it skips over it entirely when unpacking the suitcase. ## 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 **Useless Padding Socks** into the corners. This is why a table with `(int, char(1), int)` might actually take up more space than `(int, int, char(1))`. The order of your belongings matters! ## 4. TOAST (Oversized Attribute Storage) If a single item is too big for the suitcase (usually > 2KB), the elephant won't struggle with it. It 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 [[Postgres/Structures/Page]] limit.