diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index b38892d..157305a 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1328,7 +1328,7 @@ function comment_num_new($nid, $timestamp = 0) {
   if ($user->isAuthenticated() && module_exists('history')) {
     // Retrieve the timestamp at which the current user last viewed this node.
     if (!$timestamp) {
-      $timestamp = history_read($nid);
+      $timestamp = history_read('node', $nid);
     }
     $timestamp = ($timestamp > HISTORY_READ_LIMIT ? $timestamp : HISTORY_READ_LIMIT);
 
diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php
index 9041a55..2e9cc5b 100644
--- a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php
+++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php
@@ -111,9 +111,9 @@ public function preRender(&$values) {
     }
 
     if ($nids) {
-      $result = $this->database->query('SELECT n.nid, COUNT(c.cid) as num_comments FROM {node} n INNER JOIN {comment} c ON n.nid = c.nid
-        LEFT JOIN {history} h ON h.nid = n.nid AND h.uid = :h_uid WHERE n.nid IN (:nids)
-        AND c.changed > GREATEST(COALESCE(h.timestamp, :timestamp), :timestamp) AND c.status = :status GROUP BY n.nid', array(
+      $result = $this->database->query("SELECT n.nid, COUNT(c.cid) as num_comments FROM {node} n INNER JOIN {comment} c ON n.nid = c.nid
+        LEFT JOIN {history} h ON h.entity_id = n.nid AND h.entity_type = 'node' AND h.uid = :h_uid WHERE n.nid IN (:nids)
+        AND c.changed > GREATEST(COALESCE(h.timestamp, :timestamp), :timestamp) AND c.status = :status GROUP BY n.nid", array(
           ':status' => COMMENT_PUBLISHED,
           ':h_uid' => $user->id(),
           ':nids' => $nids,
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
index 4f11307..982da9a 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
@@ -157,7 +157,10 @@ function setEnvironment(array $info) {
 
         // comment_num_new() relies on history_read(), so ensure that no one has
         // seen the node of this comment.
-        db_delete('history')->condition('nid', $this->node->id())->execute();
+        db_delete('history')
+          ->condition('entity_id', $this->node->id())
+          ->condition('entity_type', 'node')
+          ->execute();
       }
       else {
         $cids = db_query("SELECT cid FROM {comment}")->fetchCol();
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 8c92381..ac363b9 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -790,7 +790,7 @@ function forum_forum_load($tid = NULL) {
 function _forum_topics_unread($term, $uid) {
   $query = db_select('node_field_data', 'n');
   $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $term));
-  $query->leftJoin('history', 'h', 'n.nid = h.nid AND h.uid = :uid', array(':uid' => $uid));
+  $query->leftJoin('history', 'h', "n.nid = h.entity_id AND h.entity_type = 'node' AND h.uid = :uid", array(':uid' => $uid));
   $query->addExpression('COUNT(n.nid)', 'count');
   return $query
     ->condition('status', 1)
@@ -798,7 +798,7 @@ function _forum_topics_unread($term, $uid) {
     //   language and just fall back to the default language.
     ->condition('n.default_langcode', 1)
     ->condition('n.created', HISTORY_READ_LIMIT, '>')
-    ->isNull('h.nid')
+    ->isNull('h.entity_id')
     ->addTag('node_access')
     ->execute()
     ->fetchField();
@@ -1225,9 +1225,9 @@ function _forum_user_last_visit($nid) {
   $history = &drupal_static(__FUNCTION__, array());
 
   if (empty($history)) {
-    $result = db_query('SELECT nid, timestamp FROM {history} WHERE uid = :uid', array(':uid' => $user->id()));
+    $result = db_query("SELECT entity_id, timestamp FROM {history} WHERE uid = :uid AND entity_type = 'node'", array(':uid' => $user->id()));
     foreach ($result as $t) {
-      $history[$t->nid] = $t->timestamp > HISTORY_READ_LIMIT ? $t->timestamp : HISTORY_READ_LIMIT;
+      $history[$t->entity_id] = $t->timestamp > HISTORY_READ_LIMIT ? $t->timestamp : HISTORY_READ_LIMIT;
     }
   }
   return isset($history[$nid]) ? $history[$nid] : HISTORY_READ_LIMIT;
diff --git a/core/modules/history/history.install b/core/modules/history/history.install
index dcfd871..086c8f7 100644
--- a/core/modules/history/history.install
+++ b/core/modules/history/history.install
@@ -13,13 +13,20 @@ function history_schema() {
     'description' => 'A record of which {users} have read which {node}s.',
     'fields' => array(
       'uid' => array(
-        'description' => 'The {users}.uid that read the {node} nid.',
+        'description' => 'The {users}.uid that read the entity_id.',
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
       ),
-      'nid' => array(
-        'description' => 'The {node}.nid that was read.',
+      'entity_type' => array(
+        'type' => 'varchar',
+        'not null' => TRUE,
+        'default' => 'node',
+        'length' => 255,
+        'description' => 'The entity_type of the entity was read.',
+      ),
+      'entity_id' => array(
+        'description' => 'The entity_id that was read.',
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
@@ -31,11 +38,19 @@ function history_schema() {
         'default' => 0,
       ),
     ),
-    'primary key' => array('uid', 'nid'),
+    'primary key' => array(
+      'uid',
+      'entity_id',
+      array('entity_type', 32),
+    ),
     'indexes' => array(
-      'nid' => array('nid'),
+      'history_entity' => array(
+        'entity_id',
+        array('entity_type', 32),
+      ),
     ),
   );
 
   return $schema;
 }
+
diff --git a/core/modules/history/history.module b/core/modules/history/history.module
index 38dd8ab..fb5d304 100644
--- a/core/modules/history/history.module
+++ b/core/modules/history/history.module
@@ -10,6 +10,7 @@
  */
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Session\AccountInterface;
 
 /**
  * Entities changed before this time are always shown as read.
@@ -22,34 +23,38 @@
 /**
  * Retrieves the timestamp for the current user's last view of a specified node.
  *
- * @param int $nid
- *   A node ID.
+ * @param string $entity_type
+ *   The entity type.
+ * @param int $entity_id
+ *   The entity ID.
  *
  * @return int
  *   If a node has been previously viewed by the user, the timestamp in seconds
  *   of when the last view occurred; otherwise, zero.
  */
-function history_read($nid) {
+function history_read($entity_type, $entity_id) {
   global $user;
   $history = &drupal_static(__FUNCTION__, array());
 
-  if (!isset($history[$nid])) {
-    $history[$nid] = db_query("SELECT timestamp FROM {history} WHERE uid = :uid AND nid = :nid", array(':uid' => $user->id(), ':nid' => $nid))->fetchObject();
+  if (!isset($history[$entity_id])) {
+    $history[$entity_id] = db_query("SELECT timestamp FROM {history} WHERE uid = :uid AND entity_id = :entity_id AND entity_type = :entity_type", array(':uid' => $user->id(), ':entity_id' => $entity_id, ':entity_type' => $entity_type))->fetchObject();
   }
 
-  return (isset($history[$nid]->timestamp) ? $history[$nid]->timestamp : 0);
+  return (isset($history[$entity_id]->timestamp) ? $history[$entity_id]->timestamp : 0);
 }
 
 /**
  * Updates 'last viewed' timestamp of the specified entity for the current user.
  *
- * @param $nid
- *   The node ID that has been read.
- * @param $account
+ * @param string $entity_type
+ *   The entity type.
+ * @param int $entity_id
+ *   The entity ID that has been read.
+ * @param \Drupal\Core\Session\AccountInterface $account
  *   (optional) The user account to update the history for. Defaults to the
  *   current user.
  */
-function history_write($nid, $account = NULL) {
+function history_write($entity_type, $entity_id, AccountInterface $account = NULL) {
   global $user;
 
   if (!isset($account)) {
@@ -60,7 +65,8 @@ function history_write($nid, $account = NULL) {
     db_merge('history')
       ->key(array(
         'uid' => $account->id(),
-        'nid' => $nid,
+        'entity_id' => $entity_id,
+        'entity_type' => $entity_type,
       ))
       ->fields(array('timestamp' => REQUEST_TIME))
       ->execute();
@@ -81,7 +87,8 @@ function history_cron() {
  */
 function history_node_delete(EntityInterface $node) {
   db_delete('history')
-    ->condition('nid', $node->id())
+    ->condition('entity_id', $node->id())
+    ->condition('entity_type', 'node')
     ->execute();
 }
 
diff --git a/core/modules/history/history.views.inc b/core/modules/history/history.views.inc
index ed36820..9bf753b 100644
--- a/core/modules/history/history.views.inc
+++ b/core/modules/history/history.views.inc
@@ -24,8 +24,9 @@ function history_views_data() {
     'node' => array(
       'table' => 'history',
       'left_field' => 'nid',
-      'field' => 'nid',
+      'field' => 'entity_id',
       'extra' => array(
+        array('field' => 'entity_type', 'value' => 'node'),
         array('field' => 'uid', 'value' => '***CURRENT_USER***', 'numeric' => TRUE),
       ),
     ),
diff --git a/core/modules/history/lib/Drupal/history/Tests/Views/HistoryTimestampTest.php b/core/modules/history/lib/Drupal/history/Tests/Views/HistoryTimestampTest.php
index 182174c..6eaca65 100644
--- a/core/modules/history/lib/Drupal/history/Tests/Views/HistoryTimestampTest.php
+++ b/core/modules/history/lib/Drupal/history/Tests/Views/HistoryTimestampTest.php
@@ -54,14 +54,16 @@ public function testHandlers() {
     db_insert('history')
       ->fields(array(
         'uid' => $account->id(),
-        'nid' => $nodes[0]->id(),
+        'entity_id' => $nodes[0]->id(),
+        'entity_type' => 'node',
         'timestamp' => REQUEST_TIME - 100,
       ))->execute();
 
     db_insert('history')
       ->fields(array(
         'uid' => $account->id(),
-        'nid' => $nodes[1]->id(),
+        'entity_id' => $nodes[1]->id(),
+        'entity_type' => 'node',
         'timestamp' => REQUEST_TIME + 100,
       ))->execute();
 
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 84117d5..20bc12b 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -693,9 +693,37 @@ function node_update_8011() {
 }
 
 /**
- * Enable History module.
+ * Convert {history} table to new format and enable History module.
  */
 function node_update_8012() {
+  // Drop all keys to properly rename constraints.
+  db_drop_primary_key('history');
+  db_drop_index('history', 'nid');
+  // Add new column.
+  db_add_field('history', 'entity_type', array(
+    'type' => 'varchar',
+    'not null' => TRUE,
+    'default' => 'node',
+    'length' => 255,
+    'description' => 'The entity_type of the entity was read.',
+  ));
+  db_change_field('history', 'nid', 'entity_id', array(
+    'description' => 'The entity_id that was read.',
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+  ));
+  // Create new indexes.
+  db_add_primary_key('history', array(
+    'uid',
+    'entity_id',
+    array('entity_type', 32),
+  ));
+  db_add_index('history', 'history_entity', array(
+    'entity_id',
+    array('entity_type', 32),
+  ));
+
   // Enable the history module without re-installing the schema.
   module_enable(array('history'));
 }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 5a6d53a..bbe39c6 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -285,7 +285,7 @@ function node_mark($nid, $timestamp) {
     return MARK_READ;
   }
   if (!isset($cache[$nid])) {
-    $cache[$nid] = history_read($nid);
+    $cache[$nid] = history_read('node', $nid);
   }
   if ($cache[$nid] == 0 && $timestamp > HISTORY_READ_LIMIT) {
     return MARK_NEW;
@@ -629,8 +629,8 @@ function node_show(EntityInterface $node, $message = FALSE) {
   $nodes = array('nodes' => node_view_multiple(array($node->id() => $node), 'full'));
 
   // Update the history table, stating that this user viewed this node.
-  if (module_exists('history')) {
-    history_write($node->id());
+  if (Drupal::moduleHandler()->moduleExists('history')) {
+    history_write('node', $node->id());
   }
 
   return $nodes;
