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 a0f7f78..6531d8d 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
@@ -83,7 +83,8 @@ function pre_render(&$values) {
       $query->addField('n', 'nid');
       $query->innerJoin('comment', 'c', 'n.nid = c.nid');
       $query->addExpression('COUNT(c.cid)', 'num_comments');
-      $query->leftJoin('history', 'h', 'h.nid = n.nid');
+      $query->leftJoin('history', 'h', 'h.entity_id = n.nid');
+      $query->condition('h.entity_type', 'node');
       $query->condition('n.nid', $nids);
       $query->where('c.changed > GREATEST(COALESCE(h.timestamp, :timestamp), :timestamp)', array(':timestamp' => HISTORY_READ_LIMIT));
       $query->condition('c.status', COMMENT_PUBLISHED);
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
index 91cab48..752daed 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
@@ -143,7 +143,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->nid)->execute();
+        db_delete('history')
+          ->condition('entity_id', $this->node->nid)
+          ->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 8b35c3e..79bd696 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -811,12 +811,12 @@ function forum_forum_load($tid = NULL) {
 function _forum_topics_unread($term, $uid) {
   $query = db_select('node', '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)
     ->condition('n.created', HISTORY_READ_LIMIT, '>')
-    ->isNull('h.nid')
+    ->isNull('h.entity_id')
     ->addTag('node_access')
     ->execute()
     ->fetchField();
@@ -1214,9 +1214,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->uid));
+    $result = db_query("SELECT entity_id, timestamp FROM {history} WHERE uid = :uid AND entity_type = 'node'", array(':uid' => $user->uid));
     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..1b05fb6 100644
--- a/core/modules/history/history.install
+++ b/core/modules/history/history.install
@@ -13,17 +13,24 @@ 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_id' => array(
+        'description' => 'The entity_id that was read.',
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
       ),
+      'entity_type' => array(
+        'type' => 'varchar',
+        'not null' => TRUE,
+        'default' => 'node',
+        'length' => 255,
+        'description' => 'The entity_type of the entity was read.',
+      ),
       'timestamp' => array(
         'description' => 'The Unix timestamp at which the read occurred.',
         'type' => 'int',
@@ -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 45027fe..8246dd4 100644
--- a/core/modules/history/history.module
+++ b/core/modules/history/history.module
@@ -22,34 +22,43 @@
 /**
  * Retrieves the timestamp for the current user's last view of a specified node.
  *
- * @param int $nid
- *   A node ID.
+ * @param int $entity_id
+ *   The entity ID.
+ * @param string $entity_type
+ *   The entity type. Defaults to "node".
  *
  * @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_id, $entity_type = 'node') {
   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->uid, ':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->uid,
+      ':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 $entity_id
+ *   The entity ID that has been read.
+ * @param $entity_type
+ *   The entity type. Defaults to "node".
  * @param $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_id, $entity_type = 'node', $account = NULL) {
   global $user;
 
   if (!isset($account)) {
@@ -60,7 +69,8 @@ function history_write($nid, $account = NULL) {
     db_merge('history')
       ->key(array(
         'uid' => $account->uid,
-        'nid' => $nid,
+        'entity_id' => $entity_id,
+        'entity_type' => $entity_type,
       ))
       ->fields(array('timestamp' => REQUEST_TIME))
       ->execute();
@@ -81,7 +91,8 @@ function history_cron() {
  */
 function history_node_delete(Node $node) {
   db_delete('history')
-    ->condition('nid', $node->nid)
+    ->condition('entity_id', $node->nid)
+    ->condition('entity_type', 'node')
     ->execute();
 }
 
@@ -93,6 +104,7 @@ function history_user_cancel($edit, $account, $method) {
     case 'user_cancel_reassign':
       db_delete('history')
         ->condition('uid', $account->uid)
+        ->condition('entity_type', 'user')
         ->execute();
       break;
   }
@@ -104,5 +116,6 @@ function history_user_cancel($edit, $account, $method) {
 function history_user_delete($account) {
   db_delete('history')
     ->condition('uid', $account->uid)
+    ->condition('entity_type', 'user')
     ->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 d92d024..1a7047e 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();
 
