Database layout¶
Compound values occupy columns in the host field's current and revision tables,
such as node__field_speakers and node_revision__field_speakers. Each row
identifies a host entity, language and outer delta; revision rows also identify
the historical revision.
Item identity¶
Every row also carries a cfi_uuid column: the UUID of that row's logical
compound item, distinct from the host's own UUID and from every other item's.
Nested items and capped slots each have their own cfi_uuid column, following
the same naming rules as any other flattened column (see below).
A compound item's revision identity is <host revision ID>:<item UUID>, split
at the final colon (a nested item's outer UUID is itself part of the host
revision address it is materialised from). CompoundFieldItem::getRevisionId()
and ::getLoadedRevisionId() both answer this composite so that
\Drupal::entityTypeManager()->getStorage('cfi_<id>')->loadRevision(...)
resolves the same historical item a host revision load already reached — not
the item's current, possibly different, default-revision row.
| Outer delta | Name | Topic slot 0 | Topic slot 1 | Topic slot 2 |
|---|---|---|---|---|
| 0 | Ada Lovelace | Computing history | Analytical engines | NULL |
| 1 | Grace Hopper | Compilers | NULL | NULL |
Direct string sub-fields produce schema keys such as name__value,
topic__value, topic__value_1 and topic__value_2. Drupal's table mapping
adds the host field prefix. References use properties such as target_id.
Unlimited outer cardinality adds rows. Raising a sub-field cap adds nullable column sets; slot zero has no suffix. Saving compacts values into dense slots. Nested compounds multiply these columns. The budget guard refuses schemas beyond InnoDB's column and row-size limits.
Long nested names use derived identifiers. Resolve physical columns through the schema and Drupal's table mapping instead of constructing names yourself. Use nested sub-field paths in the Field API and wire format.
Follow the deployment guide for schema changes.