diff --git a/core/includes/session.inc b/core/includes/session.inc
index b9b8fbc..9ffd3d1 100644
--- a/core/includes/session.inc
+++ b/core/includes/session.inc
@@ -105,9 +105,6 @@ function _drupal_session_read($sid) {
   // We found the client's session record and they are an authenticated,
   // active user.
   if ($user && $user->uid > 0 && $user->status == 1) {
-    // This is done to unserialize the data member of $user.
-    $user->data = unserialize($user->data);
-
     // Add roles element to $user.
     $user->roles = array();
     $user->roles[DRUPAL_AUTHENTICATED_RID] = DRUPAL_AUTHENTICATED_RID;
diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php
index 2660300..9b22466 100644
--- a/core/modules/user/lib/Drupal/user/UserStorageController.php
+++ b/core/modules/user/lib/Drupal/user/UserStorageController.php
@@ -29,7 +29,6 @@ function attachLoad(&$queried_users, $load_revision = FALSE) {
       if ($record->picture) {
         $picture_fids[] = $record->picture;
       }
-      $queried_users[$key]->data = unserialize($record->data);
       $queried_users[$key]->roles = array();
       if ($record->uid) {
         $queried_users[$record->uid]->roles[DRUPAL_AUTHENTICATED_RID] = DRUPAL_AUTHENTICATED_RID;
@@ -148,13 +147,6 @@ protected function preSave(EntityInterface $entity) {
     if (isset($entity->roles)) {
       $entity->roles = array_filter($entity->roles);
     }
-
-    // Move account cancellation information into $entity->data.
-    foreach (array('user_cancel_method', 'user_cancel_notify') as $key) {
-      if (isset($entity->{$key})) {
-        $entity->data[$key] = $entity->{$key};
-      }
-    }
   }
 
   /**
@@ -220,6 +212,22 @@ protected function postSave(EntityInterface $entity, $update) {
         $query->execute();
       }
     }
+
+    // Store account cancellation information.
+    foreach (array('user_cancel_method', 'user_cancel_notify') as $key) {
+      if (isset($entity->{$key})) {
+        db_merge('users_data')
+          ->key(array(
+            'uid' => $entity->uid,
+            'module' => 'user',
+            'name' => $key,
+          ))
+          ->fields(array(
+            'value' => $entity->{$key},
+          ))
+          ->execute();
+      }
+    }
   }
 
   /**
@@ -229,6 +237,9 @@ protected function postDelete($entities) {
     db_delete('users_roles')
       ->condition('uid', array_keys($entities), 'IN')
       ->execute();
+    db_delete('users_data')
+      ->condition('uid', array_keys($entities), 'IN')
+      ->execute();
     db_delete('authmap')
       ->condition('uid', array_keys($entities), 'IN')
       ->execute();
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 45d35b6..eb716b7 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -133,13 +133,6 @@ function user_schema() {
         'default' => '',
         'description' => 'E-mail address used for initial account creation.',
       ),
-      'data' => array(
-        'type' => 'blob',
-        'not null' => FALSE,
-        'size' => 'big',
-        'serialize' => TRUE,
-        'description' => 'A serialized array of name value pairs that are related to the user. Any form values posted during user edit are stored and are loaded into the $user object during user_load(). Use of this field is discouraged and it will likely disappear in a future version of Drupal.',
-      ),
     ),
     'indexes' => array(
       'access' => array('access'),
@@ -272,6 +265,48 @@ function user_schema() {
     ),
   );
 
+  $schema['users_data'] = array(
+    'description' => 'Stores variables as key/value pairs per user.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Primary Key: {users}.uid for user.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'module' => array(
+        'description' => 'The name of the module declaring the variable.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'name' => array(
+        'description' => 'The name of the variable.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'value' => array(
+        'description' => 'The serialized value of the variable.',
+        'type' => 'blob',
+        'not null' => FALSE,
+        'size' => 'big',
+        'serialize' => TRUE,
+      ),
+    ),
+    'primary key' => array('uid', 'name'),
+    'indexes' => array(
+      'name' => array('name'),
+      'uid_module' => array('uid', 'module'),
+    ),
+    'foreign keys' => array(
+      'uid' => array('users' => 'uid'),
+    ),
+  );
+
   $schema['users_roles'] = array(
     'description' => 'Maps users to roles.',
     'fields' => array(
@@ -584,5 +619,112 @@ function user_update_8008() {
 }
 
 /**
+ * Move {users}.data into an own {users_data} table.
+ */
+function user_update_8009() {
+  // Create new {users_data} table.
+  db_create_table('users_data', array(
+    'description' => 'Stores variables as key/value pairs per user.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Primary Key: {users}.uid for user.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'module' => array(
+        'description' => 'The name of the module declaring the variable.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'name' => array(
+        'description' => 'The name of the variable.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'value' => array(
+        'description' => 'The serialized value of the variable.',
+        'type' => 'blob',
+        'not null' => FALSE,
+        'size' => 'big',
+        'serialize' => TRUE,
+      ),
+    ),
+    'primary key' => array('uid', 'name'),
+    'indexes' => array(
+      'name' => array('name'),
+      'uid_module' => array('uid', 'module'),
+    ),
+    'foreign keys' => array(
+      'uid' => array('users' => 'uid'),
+    ),
+  ));
+
+  // Create backup table for data migration.
+  // Since the origin/owner of individual values in {users}.data is unknown,
+  // other modules need to migrate their existing values from {_d7_users_data}
+  // after this update has run.
+  db_create_table('_d7_users_data', array(
+    'description' => 'Backup of {users}.data for migration.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Primary Key: {users}.uid for user.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'name' => array(
+        'description' => 'The name of the variable.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'value' => array(
+        'description' => 'The serialized value of the variable.',
+        'type' => 'blob',
+        'not null' => FALSE,
+        'size' => 'big',
+        'serialize' => TRUE,
+      ),
+    ),
+    'primary key' => array('uid'),
+    'foreign keys' => array(
+      'uid' => array('users' => 'uid'),
+    ),
+  ));
+
+  // Backup existing data.
+  // @todo Process in chunks of 100 users.
+  $result = db_query("SELECT uid, data FROM {users}")->fetchAllAssoc('uid');
+  $query = db_insert('_d7_users_data')->fields(array('uid', 'name', 'value'));
+  foreach ($result as $uid => $account) {
+    if (empty($account->data)) {
+      continue;
+    }
+    $account->data = unserialize($account->data);
+    if (!empty($account->data) && is_array($account->data)) {
+      foreach ($account->data as $name => $value) {
+        $query->values(array(
+          'uid' => $uid,
+          'name' => $name,
+          'value' => serialize($value),
+        ));
+      }
+    }
+  }
+  $query->execute();
+
+  // Delete {users}.data.
+  db_drop_field('users', 'data');
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x".
  */
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index e42002b..37d767d 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -2936,14 +2936,13 @@ function user_node_load($nodes, $types) {
     $uids[$nid] = $node->uid;
   }
 
-  // Fetch name, picture, and data for these users.
-  $user_fields = db_query("SELECT uid, name, picture, data FROM {users} WHERE uid IN (:uids)", array(':uids' => $uids))->fetchAllAssoc('uid');
+  // Fetch name and picture for these users.
+  $user_fields = db_query("SELECT uid, name, picture FROM {users} WHERE uid IN (:uids)", array(':uids' => $uids))->fetchAllAssoc('uid');
 
   // Add these values back into the node objects.
   foreach ($uids as $nid => $uid) {
     $nodes[$nid]->name = $user_fields[$uid]->name;
     $nodes[$nid]->picture = $user_fields[$uid]->picture;
-    $nodes[$nid]->data = $user_fields[$uid]->data;
   }
 }
 
@@ -3079,6 +3078,10 @@ function user_modules_uninstalled($modules) {
    db_delete('role_permission')
      ->condition('module', $modules, 'IN')
      ->execute();
+  // Remove any potentially orphan module data stored for users.
+  db_delete('users_data')
+    ->condition('module', $modules, 'IN')
+    ->execute();
 }
 
 /**
