diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
index 11782fc1ca..97358dcf4e 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php
@@ -189,7 +189,7 @@ public static function open(array &$connection_options = []) {
     ];
 
     $connection_options['init_commands'] += [
-      'sql_mode' => "SET sql_mode = 'ANSI,TRADITIONAL'",
+      'sql_mode' => "SET sql_mode = 'ANSI,TRADITIONAL,NO_AUTO_VALUE_ON_ZERO'",
     ];
 
     // Execute initial commands.
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index ba319da7a1..0e593e42a9 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -1057,7 +1057,12 @@ protected function mapToStorageRecord(ContentEntityInterface $entity, $table_nam
         // SQL database drivers.
         // @see https://www.drupal.org/node/2279395
         $value = SqlContentEntityStorageSchema::castValue($definition->getSchema()['columns'][$column_name], $value);
-        if (!(empty($value) && $this->isColumnSerial($table_name, $schema_name))) {
+        $empty_serial = empty($value) && $this->isColumnSerial($table_name, $schema_name);
+        // The user entity is a very special case where the ID field is a serial
+        // but we need to insert a row with an ID of 0 to represent the
+        // anonymous user.
+        $user_zero = $this->entityTypeId === 'user' && $value === 0;
+        if (!$empty_serial || $user_zero) {
           $record->$schema_name = $value;
         }
       }
diff --git a/core/modules/user/src/UserStorage.php b/core/modules/user/src/UserStorage.php
index a2adfe9118..eb47af1539 100644
--- a/core/modules/user/src/UserStorage.php
+++ b/core/modules/user/src/UserStorage.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\user;
 
-use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
 use Drupal\Core\Session\AccountInterface;
 
@@ -14,27 +13,6 @@
  */
 class UserStorage extends SqlContentEntityStorage implements UserStorageInterface {
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = []) {
-    // The anonymous user account is saved with the fixed user ID of 0.
-    // Therefore we need to check for NULL explicitly.
-    if ($entity->id() === NULL) {
-      $entity->uid->value = $this->database->nextId($this->database->query('SELECT MAX([uid]) FROM {' . $this->getBaseTable() . '}')->fetchField());
-      $entity->enforceIsNew();
-    }
-    return parent::doSaveFieldItems($entity, $names);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function isColumnSerial($table_name, $schema_name) {
-    // User storage does not use a serial column for the user id.
-    return $table_name == $this->revisionTable && $schema_name == $this->revisionKey;
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/user/src/UserStorageSchema.php b/core/modules/user/src/UserStorageSchema.php
index 6ac14d26d8..d172fb3a6a 100644
--- a/core/modules/user/src/UserStorageSchema.php
+++ b/core/modules/user/src/UserStorageSchema.php
@@ -26,16 +26,6 @@ protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $res
     return $schema;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function processIdentifierSchema(&$schema, $key) {
-    // The "users" table does not use serial identifiers.
-    if ($key != $this->entityType->getKey('id')) {
-      parent::processIdentifierSchema($schema, $key);
-    }
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 8375992ce7..370538ae06 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -97,3 +97,12 @@ function user_install() {
 function user_update_last_removed() {
   return 8100;
 }
+
+/**
+ * Change the users table to use an serial uid field.
+ */
+function user_update_9001(&$sandbox) {
+  $schema = \Drupal::database()->schema();
+  $schema->dropPrimaryKey('users');
+  $schema->changeField('users', 'uid', 'uid', ['type' => 'serial', 'not null' => TRUE], ['primary key' => ['uid']]);
+}
