entity table structure isn't clearly documented

Created on 27 July 2021, about 3 years ago
Updated 11 June 2024, 3 months ago

Problem/Motivation

Content entities that use SQL storage (which are most of them in core and in contrib) have a table schema that can involve up to 4 tables for base fields:

- base table
- data table
- revision table
- revision data table

Whether all 4 tables exist depends on whether the entity type is translatable or revisionable, and base fields go in different tables (or more than one table!) based on their own translatability or revisionability.

This is fairly complicated to understand!

There does not appear to be a single place that explains this all clearly in the documentation.

The best explanation that I can find is this sequence of inline comments in DefaultTableMapping:

    if (!$revisionable && !$translatable) {
      // The base layout stores all the base field values in the base table.
      $table_mapping->setFieldNames($table_mapping->baseTable, $all_fields);
    }
    elseif ($revisionable && !$translatable) {
      // The revisionable layout stores all the base field values in the base
      // table, except for revision metadata fields. Revisionable fields
      // denormalized in the base table but also stored in the revision table
      // together with the entity ID and the revision ID as identifiers.
      $table_mapping->setFieldNames($table_mapping->baseTable, array_diff($all_fields, $revision_metadata_fields));
      $revision_key_fields = [$id_key, $revision_key];
      $table_mapping->setFieldNames($table_mapping->revisionTable, array_merge($revision_key_fields, $revisionable_fields));
    }
    elseif (!$revisionable && $translatable) {
      // Multilingual layouts store key field values in the base table. The
      // other base field values are stored in the data table, no matter
      // whether they are translatable or not. The data table holds also a
      // denormalized copy of the bundle field value to allow for more
      // performant queries. This means that only the UUID is not stored on
      // the data table.
      $table_mapping
        ->setFieldNames($table_mapping->baseTable, $key_fields)
        ->setFieldNames($table_mapping->dataTable, array_values(array_diff($all_fields, [$uuid_key])));
    }
    elseif ($revisionable && $translatable) {
      // The revisionable multilingual layout stores key field values in the
      // base table and the revision table holds the entity ID, revision ID and
      // langcode ID along with revision metadata. The revision data table holds
      // data field values for all the revisionable fields and the data table
      // holds the data field values for all non-revisionable fields. The data
      // field values of revisionable fields are denormalized in the data
      // table, as well.

      $table_mapping->setFieldNames($table_mapping->baseTable, $key_fields);

      // Like in the multilingual, non-revisionable case the UUID is not
      // in the data table. Additionally, do not store revision metadata
      // fields in the data table.

but there are snippets of useful information elsewhere too, e.g.:

      // Only the data table follows the entity language key, dedicated field
      // tables have a hard-coded 'langcode' column.
      // Since a field may be stored in more than one table, we inspect tables
      // in order of relevance: the data table if present is the main place
      // where field data is stored, otherwise the base table is responsible for
      // storing field data. Revision metadata is an exception as it's stored
      // only in the revision table.
        // Find fields that are not revisioned or entity keys. Data fields have
        // the same value regardless of entity revision.

Steps to reproduce

Proposed resolution

Add an overview to the class docs of DefaultTableMapping.

Add @see references in other places.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Active

Version

11.0 🔥

Component
Documentation 

Last updated 1 minute ago

No maintainer
Created by

🇬🇧United Kingdom joachim

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024