diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
index 8ee00bd6236c2b46d85c10862a6b81338a01886d..b229d3a6180f4915eabb27729b9db3e702593f3d 100644
--- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
+++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php
@@ -147,15 +147,16 @@ public function getFieldTableName($field_name) {
       //   https://www.drupal.org/node/2274017.
       /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
       $storage = \Drupal::entityManager()->getStorage($this->entityType->id());
+      $storage_definition = $this->fieldStorageDefinitions[$field_name];
       $table_names = array(
         $storage->getDataTable(),
         $storage->getBaseTable(),
         $storage->getRevisionTable(),
+        $this->getDedicatedDataTableName($storage_definition),
       );
 
       // Collect field columns.
       $field_columns = array();
-      $storage_definition = $this->fieldStorageDefinitions[$field_name];
       foreach (array_keys($storage_definition->getColumns()) as $property_name) {
         $field_columns[] = $this->getFieldColumnName($storage_definition, $property_name);
       }
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index a0a04673f37c343d96cd89b038cf2821f785fdea..05436513c7cba58b73e1197e10f96d7e18855656 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -282,13 +282,13 @@ public function getTableMapping(array $storage_definitions = NULL) {
       $definitions = $storage_definitions ?: $this->entityManager->getFieldStorageDefinitions($this->entityTypeId);
       $table_mapping = new DefaultTableMapping($this->entityType, $definitions);
 
-      $definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
+      $shared_table_definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
         return $table_mapping->allowsSharedTableStorage($definition);
       });
 
       $key_fields = array_values(array_filter(array($this->idKey, $this->revisionKey, $this->bundleKey, $this->uuidKey, $this->langcodeKey)));
-      $all_fields = array_keys($definitions);
-      $revisionable_fields = array_keys(array_filter($definitions, function (FieldStorageDefinitionInterface $definition) {
+      $all_fields = array_keys($shared_table_definitions);
+      $revisionable_fields = array_keys(array_filter($shared_table_definitions, function (FieldStorageDefinitionInterface $definition) {
         return $definition->isRevisionable();
       }));
       // Make sure the key fields come first in the list of fields.
@@ -355,7 +355,7 @@ public function getTableMapping(array $storage_definitions = NULL) {
       }
 
       // Add dedicated tables.
-      $definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
+      $dedicated_table_definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
         return $table_mapping->requiresDedicatedTableStorage($definition);
       });
       $extra_columns = array(
@@ -366,8 +366,12 @@ public function getTableMapping(array $storage_definitions = NULL) {
         'langcode',
         'delta',
       );
-      foreach ($definitions as $field_name => $definition) {
-        foreach (array($table_mapping->getDedicatedDataTableName($definition), $table_mapping->getDedicatedRevisionTableName($definition)) as $table_name) {
+      foreach ($dedicated_table_definitions as $field_name => $definition) {
+        $tables = [$table_mapping->getDedicatedDataTableName($definition)];
+        if ($revisionable && $definition->isRevisionable()) {
+          $tables[] = $table_mapping->getDedicatedRevisionTableName($definition);
+        }
+        foreach ($tables as $table_name) {
           $table_mapping->setFieldNames($table_name, array($field_name));
           $table_mapping->setExtraColumns($table_name, $extra_columns);
         }
@@ -1582,7 +1586,13 @@ public function finalizePurge(FieldStorageDefinitionInterface $storage_definitio
    * {@inheritdoc}
    */
   public function countFieldData($storage_definition, $as_bool = FALSE) {
-    $table_mapping = $this->getTableMapping();
+    // The table mapping contains stale data during a request when a field
+    // storage definition is added, so bypass the internal storage definitions
+    // and fetch the table mapping using the passed in storage definition.
+    // @todo Fix this in https://www.drupal.org/node/2705205.
+    $storage_definitions = $this->entityManager->getFieldStorageDefinitions($this->entityTypeId);
+    $storage_definitions[$storage_definition->getName()] = $storage_definition;
+    $table_mapping = $this->getTableMapping($storage_definitions);
 
     if ($table_mapping->requiresDedicatedTableStorage($storage_definition)) {
       $is_deleted = $this->storageDefinitionIsDeleted($storage_definition);
diff --git a/core/modules/system/src/Tests/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php b/core/modules/system/src/Tests/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php
index 19384c9b100c8693893c955453784c29e228ae5c..ceab801e3c0dee5268333505575e6a68322eee96 100644
--- a/core/modules/system/src/Tests/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php
+++ b/core/modules/system/src/Tests/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php
@@ -67,6 +67,9 @@ public function testSingleUpdates() {
     $this->enableUpdates('entity_test', 'entity_definition_updates', 8001);
     $this->applyUpdates();
 
+    // Ensure the 'entity_test__user_id' table got created.
+    $this->assertTrue(\Drupal::database()->schema()->tableExists('entity_test__user_id'));
+
     // Check that data was correctly migrated.
     $entity = $this->reloadEntity($entity);
     $this->assertEqual(count($entity->user_id), 1);
diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php
index d8dc82f8f2dc1c37c3a06f18e449cfc8da694969..e41efa9d3a883d7d37232fc6c39df2d6fbbda7f0 100644
--- a/core/modules/views/src/EntityViewsData.php
+++ b/core/modules/views/src/EntityViewsData.php
@@ -235,7 +235,7 @@ public function getViewsData() {
     // Load all typed data definitions of all fields. This should cover each of
     // the entity base, revision, data tables.
     $field_definitions = $this->entityManager->getBaseFieldDefinitions($this->entityType->id());
-    if ($table_mapping = $this->storage->getTableMapping()) {
+    if ($table_mapping = $this->storage->getTableMapping($field_definitions)) {
       // Fetch all fields that can appear in both the base table and the data
       // table.
       $entity_keys = $this->entityType->getKeys();
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8f945b3cba90bb5454119a5a42bf89e7820f2ae8
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Entity/DefaultTableMappingIntegrationTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Entity;
+
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+
+/**
+ * Tests the default table mapping class for content entities stored in SQL.
+ *
+ * @see \Drupal\Core\Entity\Sql\DefaultTableMapping
+ * @see \Drupal\Core\Entity\Sql\TableMappingInterface
+ *
+ * @coversDefaultClass \Drupal\Core\Entity\Sql\DefaultTableMapping
+ * @group Entity
+ */
+class DefaultTableMappingIntegrationTest extends EntityKernelTestBase {
+
+  /**
+   * The table mapping for the tested entity type.
+   *
+   * @var \Drupal\Core\Entity\Sql\TableMappingInterface
+   */
+  protected $tableMapping;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['entity_test_extra'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Setup some fields for entity_test_extra to create.
+    $definitions['multivalued_base_field'] = BaseFieldDefinition::create('string')
+      ->setName('multivalued_base_field')
+      ->setTargetEntityTypeId('entity_test_mulrev')
+      ->setTargetBundle('entity_test_mulrev')
+      ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
+    $this->state->set('entity_test_mulrev.additional_base_field_definitions', $definitions);
+
+    $this->entityManager->clearCachedDefinitions();
+    $this->tableMapping = $this->entityManager->getStorage('entity_test_mulrev')->getTableMapping();
+  }
+
+  /**
+   * Tests DefaultTableMapping::getFieldTableName().
+   *
+   * @covers ::getFieldTableName
+   */
+  public function testGetFieldTableName() {
+    // Test the field table name for a single-valued base field, which is stored
+    // in the entity's base table.
+    $expected = 'entity_test_mulrev';
+    $this->assertEquals($this->tableMapping->getFieldTableName('uuid'), $expected);
+
+    // Test the field table name for a translatable and revisionable base field,
+    // which is stored in the entity's data table.
+    $expected = 'entity_test_mulrev_property_data';
+    $this->assertEquals($this->tableMapping->getFieldTableName('name'), $expected);
+
+    // Test the field table name for a multi-valued base field, which is stored
+    // in a dedicated table.
+    $expected = 'entity_test_mulrev__multivalued_base_field';
+    $this->assertEquals($this->tableMapping->getFieldTableName('multivalued_base_field'), $expected);
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
index 34013c488a9de8b38a528a51fdc3f39e39695f0e..02970d7256baafec1edda03332cf486b301c7ea7 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
@@ -466,6 +466,42 @@ public function providerTestGetTableMappingSimple() {
     );
   }
 
+  /**
+   * Tests getTableMapping() with a base field that requires a dedicated table.
+   *
+   * @covers ::__construct
+   * @covers ::getTableMapping
+   */
+  public function testGetTableMappingSimpleWithDedicatedStorageFields() {
+    $base_field_names = ['multi_valued_base_field'];
+
+    // Set up one entity key in order to have a base table.
+    $this->fieldDefinitions = $this->mockFieldDefinitions(['test_id']);
+
+    // Set up the multi-valued base field.
+    $this->fieldDefinitions += $this->mockFieldDefinitions($base_field_names, [
+      'hasCustomStorage' => FALSE,
+      'isMultiple' => TRUE,
+      'getTargetEntityTypeId' => 'entity_test',
+    ]);
+
+    $this->setUpEntityStorage();
+
+    $mapping = $this->entityStorage->getTableMapping();
+    $this->assertEquals(['entity_test', 'entity_test__multi_valued_base_field'], $mapping->getTableNames());
+    $this->assertEquals($base_field_names, $mapping->getFieldNames('entity_test__multi_valued_base_field'));
+
+    $extra_columns = array(
+      'bundle',
+      'deleted',
+      'entity_id',
+      'revision_id',
+      'langcode',
+      'delta',
+    );
+    $this->assertEquals($extra_columns, $mapping->getExtraColumns('entity_test__multi_valued_base_field'));
+  }
+
   /**
    * Tests getTableMapping() with a revisionable, non-translatable entity type.
    *