diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
index e18edbd..7cc7a08 100644
--- a/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
+++ b/core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
@@ -483,7 +483,9 @@ protected function mapToDataStorageRecord(EntityInterface $entity, $langcode) {
 
     $record = new \stdClass();
     foreach ($this->entityInfo['schema_fields_sql']['data_table'] as $name) {
-      $record->$name = $translation->$name->value;
+      if (isset($translation->$name->value)) {
+        $record->$name = $translation->$name->value;
+      }
     }
     $record->langcode = $langcode;
     $record->default_langcode = intval($default_langcode == $langcode);
diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorageController.php
index c9e832e..aefc0d2 100644
--- a/core/modules/node/lib/Drupal/node/NodeStorageController.php
+++ b/core/modules/node/lib/Drupal/node/NodeStorageController.php
@@ -80,21 +80,6 @@ protected function attachLoad(&$queried_entities, $load_revision = FALSE) {
   }
 
   /**
-   * Overrides Drupal\Core\Entity\DatabaseStorageController::buildQuery().
-   */
-  protected function buildQuery($ids, $revision_id = FALSE) {
-    // Ensure that uid is taken from the {node} table,
-    // alias timestamp to revision_timestamp and add revision_uid.
-    $query = parent::buildQuery($ids, $revision_id);
-    $fields =& $query->getFields();
-    unset($fields['timestamp']);
-    $query->addField('revision', 'timestamp', 'revision_timestamp');
-    $fields['uid']['table'] = 'base';
-    $query->addField('revision', 'uid', 'revision_uid');
-    return $query;
-  }
-
-  /**
    * Overrides Drupal\Core\Entity\DatabaseStorageController::invokeHook().
    */
   protected function invokeHook($hook, EntityInterface $node) {
@@ -129,6 +114,16 @@ protected function invokeHook($hook, EntityInterface $node) {
   }
 
   /**
+   * Overrides \Drupal\Core\Entity\DatabaseStorageControllerNG::mapToDataStorageRecord().
+   */
+  protected function mapToDataStorageRecord(EntityInterface $entity, $langcode) {
+    // @todo Remove this once comment is a regular entity field.
+    $record = parent::mapToDataStorageRecord($entity, $langcode);
+    $record->comment = intval($record->comment);
+    return $record;
+  }
+
+  /**
    * Overrides Drupal\Core\Entity\DatabaseStorageController::preSave().
    */
   protected function preSave(EntityInterface $node) {
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
index e367425..c1bf677 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Entity/Node.php
@@ -27,7 +27,8 @@
  *   },
  *   translation_controller_class = "Drupal\node\NodeTranslationController",
  *   base_table = "node",
- *   revision_table = "node_revision",
+ *   data_table = "node_property_data",
+ *   revision_table = "node_property_revision",
  *   uri_callback = "node_uri",
  *   fieldable = TRUE,
  *   translatable = TRUE,
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index ebbce13..573bdba0 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -27,7 +27,7 @@ function node_schema() {
       // Defaults to NULL in order to avoid a brief period of potential
       // deadlocks on the index.
       'vid' => array(
-        'description' => 'The current {node_revision}.vid version identifier.',
+        'description' => 'The current {node_property_revision}.vid version identifier.',
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => FALSE,
@@ -47,56 +47,8 @@ function node_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
-      'title' => array(
-        'description' => 'The title of this node, always treated as non-markup plain text.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'uid' => array(
-        'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'status' => array(
-        'description' => 'Boolean indicating whether the node is published (visible to non-administrators).',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 1,
-      ),
-      'created' => array(
-        'description' => 'The Unix timestamp when the node was created.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'changed' => array(
-        'description' => 'The Unix timestamp when the node was most recently saved.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'comment' => array(
-        'description' => 'Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'promote' => array(
-        'description' => 'Boolean indicating whether the node should be displayed on the front page.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'sticky' => array(
-        'description' => 'Boolean indicating whether the node should be displayed at the top of lists in which it appears.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
+      // @todo Remove the following columns when removing the legacy Content
+      //   Translation module.
       'tnid' => array(
         'description' => 'The translation set id for this node, which equals the node id of the source post in each set.',
         'type' => 'int',
@@ -112,15 +64,9 @@ function node_schema() {
       ),
     ),
     'indexes' => array(
-      'node_changed'        => array('changed'),
-      'node_created'        => array('created'),
-      'node_frontpage'      => array('promote', 'status', 'sticky', 'created'),
-      'node_status_type'    => array('status', 'type', 'nid'),
-      'node_title_type'     => array('title', array('type', 4)),
-      'node_type'           => array(array('type', 4)),
-      'uid'                 => array('uid'),
-      'tnid'                => array('tnid'),
-      'translate'           => array('translate'),
+      'node_type' => array(array('type', 4)),
+      'tnid' => array('tnid'),
+      'translate' => array('translate'),
     ),
     'unique keys' => array(
       'vid' => array('vid'),
@@ -128,76 +74,118 @@ function node_schema() {
     ),
     'foreign keys' => array(
       'node_revision' => array(
-        'table' => 'node_revision',
+        'table' => 'node_property_revision',
         'columns' => array('vid' => 'vid'),
       ),
-      'node_author' => array(
-        'table' => 'users',
-        'columns' => array('uid' => 'uid'),
-      ),
     ),
     'primary key' => array('nid'),
   );
 
-  $schema['node_access'] = array(
-    'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
+  // Node property storage.
+  $schema['node_property_data'] = array(
+    'description' => 'Base table for node properties.',
     'fields' => array(
       'nid' => array(
-        'description' => 'The {node}.nid this record affects.',
-        'type' => 'int',
+        'description' => 'The primary identifier for a node.',
+        'type' => 'serial',
         'unsigned' => TRUE,
         'not null' => TRUE,
-        'default' => 0,
       ),
-      'gid' => array(
-        'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
+      'vid' => array(
+        'description' => 'The current {node_property_revision}.vid version identifier.',
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
-        'default' => 0,
       ),
-      'realm' => array(
-        'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
+      'langcode' => array(
+        'description' => 'The {language}.langcode of these node property values.',
+        'type' => 'varchar',
+        'length' => 12,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'default_langcode' => array(
+        'description' => 'Boolean indicating whether the property values are in the {language}.langcode of this node.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 1,
+      ),
+      'title' => array(
+        'description' => 'The title of this node, always treated as non-markup plain text.',
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
         'default' => '',
       ),
-      'grant_view' => array(
-        'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
+      'uid' => array(
+        'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
-        'size' => 'tiny',
       ),
-      'grant_update' => array(
-        'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
+      'status' => array(
+        'description' => 'Boolean indicating whether the node translation is published (visible to non-administrators).',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 1,
+      ),
+      'created' => array(
+        'description' => 'The Unix timestamp when the node translation was created.',
         'type' => 'int',
-        'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
-        'size' => 'tiny',
       ),
-      'grant_delete' => array(
-        'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
+      'changed' => array(
+        'description' => 'The Unix timestamp when the node translation was most recently saved.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'comment' => array(
+        'description' => 'Whether comments are allowed on this node translation: 0 = no, 1 = closed (read only), 2 = open (read/write).',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'promote' => array(
+        'description' => 'Boolean indicating whether the node translation should be displayed on the front page.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'sticky' => array(
+        'description' => 'Boolean indicating whether the node translation should be displayed at the top of lists in which it appears.',
         'type' => 'int',
-        'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
-        'size' => 'tiny',
       ),
     ),
-    'primary key' => array('nid', 'gid', 'realm'),
+    'indexes' => array(
+      'node_changed' => array('changed'),
+      'node_created' => array('created'),
+      'node_frontpage' => array('promote', 'status', 'sticky', 'created'),
+      // @todo Figure out how to replace the 'node_status_type' and the
+      //   'node_title_type' indexes.
+      'nid' => array('nid'),
+      'vid' => array('vid'),
+      'uid' => array('uid'),
+    ),
     'foreign keys' => array(
-      'affected_node' => array(
+      'node_base' => array(
         'table' => 'node',
         'columns' => array('nid' => 'nid'),
       ),
-     ),
+      'node_author' => array(
+        'table' => 'users',
+        'columns' => array('uid' => 'uid'),
+      ),
+    ),
+    'primary key' => array('nid', 'vid', 'langcode'),
   );
 
-  $schema['node_revision'] = array(
+  // Node property revision storage.
+  $schema['node_property_revision'] = array(
     'description' => 'Stores information about each saved version of a {node}.',
     'fields' => array(
       'nid' => array(
@@ -205,7 +193,6 @@ function node_schema() {
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
-        'default' => 0,
       ),
       'vid' => array(
         'description' => 'The primary identifier for this version.',
@@ -213,29 +200,30 @@ function node_schema() {
         'unsigned' => TRUE,
         'not null' => TRUE,
       ),
-      'uid' => array(
-        'description' => 'The {users}.uid that created this version.',
+      'langcode' => array(
+        'description' => 'The {language}.langcode of this version.',
+        'type' => 'varchar',
+        'length' => 12,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'default_langcode' => array(
+        'description' => 'Boolean indicating whether the property values of this version are in the {language}.langcode of this node.',
         'type' => 'int',
-        'unsigned' => TRUE,
         'not null' => TRUE,
-        'default' => 0,
+        'default' => 1,
       ),
       'title' => array(
-        'description' => 'The title of this version.',
+        'description' => 'The title of this version, always treated as non-markup plain text.',
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
         'default' => '',
       ),
-      'log' => array(
-        'description' => 'The log entry explaining the changes in this version.',
-        'type' => 'text',
-        'not null' => TRUE,
-        'size' => 'big',
-      ),
-      'timestamp' => array(
-        'description' => 'A Unix timestamp indicating when this version was created.',
+      'uid' => array(
+        'description' => 'The {users}.uid that created this version.',
         'type' => 'int',
+        'unsigned' => TRUE,
         'not null' => TRUE,
         'default' => 0,
       ),
@@ -245,6 +233,18 @@ function node_schema() {
         'not null' => TRUE,
         'default' => 1,
       ),
+      'created' => array(
+        'description' => 'The Unix timestamp when the version was created.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'changed' => array(
+        'description' => 'The Unix timestamp when the version was most recently saved.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'comment' => array(
         'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).',
         'type' => 'int',
@@ -263,12 +263,18 @@ function node_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
+      'log' => array(
+        'description' => 'The log entry explaining the changes in this version.',
+        'type' => 'text',
+        'not null' => FALSE,
+        'size' => 'big',
+      ),
     ),
     'indexes' => array(
       'nid' => array('nid'),
       'uid' => array('uid'),
+      'vid' => array('vid'),
     ),
-    'primary key' => array('vid'),
     'foreign keys' => array(
       'versioned_node' => array(
         'table' => 'node',
@@ -279,6 +285,65 @@ function node_schema() {
         'columns' => array('uid' => 'uid'),
       ),
     ),
+    'primary key' => array('nid', 'vid', 'langcode'),
+  );
+
+  $schema['node_access'] = array(
+    'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
+    'fields' => array(
+      'nid' => array(
+        'description' => 'The {node}.nid this record affects.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'gid' => array(
+        'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'realm' => array(
+        'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'grant_view' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+      'grant_update' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+      'grant_delete' => array(
+        'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+    ),
+    'primary key' => array('nid', 'gid', 'realm'),
+    'foreign keys' => array(
+      'affected_node' => array(
+        'table' => 'node',
+        'columns' => array('nid' => 'nid'),
+      ),
+    ),
   );
 
   $schema['node_type'] = array(
@@ -361,7 +426,7 @@ function node_schema() {
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
-        'size' => 'tiny'
+        'size' => 'tiny',
       ),
       'orig_type' => array(
         'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.',
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 0b7262c..e14ab3d 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1606,7 +1606,7 @@ function _node_revision_access(EntityInterface $node, $op = 'view', $account = N
     // different revisions so there is no need for a separate database check.
     // Also, if you try to revert to or delete the default revision, that's
     // not good.
-    if ($node->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField() == 1 || $op == 'update' || $op == 'delete')) {
+    if ($node->isDefaultRevision() && (db_query('SELECT COUNT(vid) FROM {node_property_revision} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField() == 1 || $op == 'update' || $op == 'delete')) {
       $access[$cid] = FALSE;
     }
     elseif (user_access('administer nodes', $account)) {
@@ -1857,7 +1857,7 @@ function node_page_title(EntityInterface $node) {
  *   A unix timestamp indicating the last time the node was changed.
  */
 function node_last_changed($nid) {
-  return db_query('SELECT changed FROM {node} WHERE nid = :nid', array(':nid' => $nid))->fetch()->changed;
+  return db_query('SELECT changed FROM {node_property_data} WHERE nid = :nid', array(':nid' => $nid))->fetch()->changed;
 }
 
 /**
