diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index 3f15f43..9c32b53 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -53,8 +53,21 @@ public function __construct(Connection $connection, $bin) {
    * Implements Drupal\Core\Cache\CacheBackendInterface::get().
    */
   public function get($cid, $allow_invalid = FALSE) {
-    $cids = array($cid);
-    $cache = $this->getMultiple($cids, $allow_invalid);
+    $cidhash = self::cidhash($cid);
+    $result = array();
+    try {
+      $result = $this->connection->query('SELECT cid, data, created, expire, serialized, tags, checksum_invalidations, checksum_deletions FROM {' . $this->connection->escapeTable($this->bin) . '} WHERE cidhash = :cidhash', array(':cidhash' => $cidhash));
+    }
+    catch (\Exception $e) {
+      // Nothing to do.
+    }
+    $cache = array();
+    foreach ($result as $item) {
+      $item = $this->prepareItem($item, $allow_invalid);
+      if ($item) {
+        $cache[$item->cid] = $item;
+      }
+    }
     return reset($cache);
   }
 
@@ -62,6 +75,7 @@ public function get($cid, $allow_invalid = FALSE) {
    * Implements Drupal\Core\Cache\CacheBackendInterface::getMultiple().
    */
   public function getMultiple(&$cids, $allow_invalid = FALSE) {
+    $hashes = array_values(array_map('self::cidhash', $cids));
     // When serving cached pages, the overhead of using ::select() was found
     // to add around 30% overhead to the request. Since $this->bin is a
     // variable, this means the call to ::query() here uses a concatenated
@@ -71,7 +85,7 @@ public function getMultiple(&$cids, $allow_invalid = FALSE) {
     // ::select() is a much smaller proportion of the request.
     $result = array();
     try {
-      $result = $this->connection->query('SELECT cid, data, created, expire, serialized, tags, checksum_invalidations, checksum_deletions FROM {' . $this->connection->escapeTable($this->bin) . '} WHERE cid IN (:cids)', array(':cids' => $cids));
+      $result = $this->connection->query('SELECT cid, data, created, expire, serialized, tags, checksum_invalidations, checksum_deletions FROM {' . $this->connection->escapeTable($this->bin) . '} WHERE cidhash IN (:cidshash)', array(':cidshash' => $hashes));
     }
     catch (\Exception $e) {
       // Nothing to do.
@@ -160,6 +174,13 @@ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array
   }
 
   /**
+   * Calculate a consistent-length cache ID.
+   */
+  protected static function cidhash($cid) {
+    return rtrim(base64_encode(hash('sha512', $cid, TRUE)), '=');
+  }
+
+  /**
    * Actually set the cache.
    */
   protected function doSet($cid, $data, $expire, $tags) {
@@ -179,6 +200,7 @@ protected function doSet($cid, $data, $expire, $tags) {
     }
     $checksum = $this->checksumTags($flat_tags);
     $fields = array(
+      'cid' => $cid,
       'serialized' => 0,
       'created' => REQUEST_TIME,
       'expire' => $expire,
@@ -196,7 +218,7 @@ protected function doSet($cid, $data, $expire, $tags) {
     }
 
     $this->connection->merge($this->bin)
-      ->key('cid', $cid)
+      ->keys(array('cidhash'), array(self::cidhash($cid)))
       ->fields($fields)
       ->execute();
   }
@@ -219,7 +241,7 @@ public function setMultiple(array $items) {
 
       $query = $this->connection
         ->insert($this->bin)
-        ->fields(array('cid', 'data', 'expire', 'created', 'serialized', 'tags', 'checksum_invalidations', 'checksum_deletions'));
+        ->fields(array('cidhash', 'cid', 'data', 'expire', 'created', 'serialized', 'tags', 'checksum_invalidations', 'checksum_deletions'));
 
       foreach ($items as $cid => $item) {
         $item += array(
@@ -244,6 +266,7 @@ public function setMultiple(array $items) {
         $checksum = $this->checksumTags($flat_tags);
 
         $fields = array(
+          'cidhash' => self::cidhash($cid),
           'cid' => $cid,
           'expire' => $item['expire'],
           'created' => REQUEST_TIME,
@@ -284,14 +307,14 @@ public function delete($cid) {
    * Implements Drupal\Core\Cache\CacheBackendInterface::deleteMultiple().
    */
   public function deleteMultiple(array $cids) {
+    $hashes = array_map('self::cidhash', $cids);
     try {
       // Delete in chunks when a large array is passed.
-      do {
+      foreach (array_chunk($hashes, 1000) as $chunk) {
         $this->connection->delete($this->bin)
-          ->condition('cid', array_splice($cids, 0, 1000), 'IN')
+          ->condition('cidhash', $chunk, 'IN')
           ->execute();
       }
-      while (count($cids));
     }
     catch (\Exception $e) {
       // Create the cache table, which will be empty. This fixes cases during
@@ -357,15 +380,15 @@ public function invalidate($cid) {
    * Implements Drupal\Core\Cache\CacheBackendInterface::invalideMultiple().
    */
   public function invalidateMultiple(array $cids) {
+    $hashes = array_map('self::cidhash', $cids);
     try {
       // Update in chunks when a large array is passed.
-      do {
+      foreach (array_chunk($hashes, 1000) as $chunk) {
         $this->connection->update($this->bin)
           ->fields(array('expire' => REQUEST_TIME - 1))
-          ->condition('cid', array_splice($cids, 0, 1000), 'IN')
+          ->condition('cidhash', $chunk, 'IN')
           ->execute();
       }
-      while (count($cids));
     }
     catch (\Exception $e) {
       $this->catchException($e);
@@ -555,10 +578,15 @@ public function schemaDefinition() {
     $schema['bin'] = array(
       'description' => 'Storage for the cache API.',
       'fields' => array(
+        'cidhash' => array(
+          'description' => 'Hash of the human-readable cid.',
+          'type' => 'varchar',
+          'length' => strlen(self::cidhash('value')),
+        ),
         'cid' => array(
-          'description' => 'Primary Key: Unique cache ID.',
+          'description' => 'Original (human-readable) Cache ID.',
           'type' => 'varchar',
-          'length' => 255,
+          'length' => 1000,
           'not null' => TRUE,
           'default' => '',
         ),
@@ -608,8 +636,9 @@ public function schemaDefinition() {
       ),
       'indexes' => array(
         'expire' => array('expire'),
+        'created' => array('created'),
       ),
-      'primary key' => array('cid'),
+      'primary key' => array('cidhash'),
     );
     $schema['cache_tags'] = array(
       'description' => 'Cache table for tracking cache tags related to the cache bin.',
diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
index 0a9108c..f90a689 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Cache/GenericCacheBackendUnitTestBase.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\system\Tests\Cache\GenericCacheBackendUnitTestBase.
+ * Contains \Drupal\system\Tests\Cache\GenericCacheBackendUnitTestBase.
  */
 
 namespace Drupal\system\Tests\Cache;
@@ -182,6 +182,11 @@ public function testSetGet() {
     $this->assertEqual($cached->created, REQUEST_TIME, 'Created time is correct.');
     $this->assertEqual($cached->expire, Cache::PERMANENT, 'Expire time is correct.');
 
+    // Check with a long key.
+    $cid = str_repeat('a', 300);
+    $backend->set($cid, 'test');
+    $this->assertEqual('test', $backend->get($cid)->data);
+
     $with_variable = array('foo' => '$bar');
     $backend->set('test6', $with_variable);
     $cached = $backend->get('test6');
@@ -210,6 +215,11 @@ public function testDelete() {
 
     $backend->delete('test2');
     $this->assertIdentical(FALSE, $backend->get('test2'), "Backend does not contain data for cache id test2 after deletion.");
+
+    $long_cid = str_repeat('a', 300);
+    $backend->set($long_cid, 'test');
+    $backend->delete($long_cid);
+    $this->assertIdentical(FALSE, $backend->get($long_cid), "Backend does not contain data for long cache id after deletion.");
   }
 
   /**
@@ -247,6 +257,7 @@ public function testGetMultiple() {
     $backend = $this->getCacheBackend();
 
     // Set numerous testing keys.
+    $long_cid = str_repeat('a', 300);
     $backend->set('test1', 1);
     $backend->set('test2', 3);
     $backend->set('test3', 5);
@@ -254,6 +265,7 @@ public function testGetMultiple() {
     $backend->set('test5', 11);
     $backend->set('test6', 13);
     $backend->set('test7', 17);
+    $backend->set($long_cid, 300);
 
     // Mismatch order for harder testing.
     $reference = array(
@@ -321,6 +333,11 @@ public function testGetMultiple() {
     $this->assertFalse(in_array('test2', $cids), "Existing cache id test2 is not in cids array.");
     $this->assertFalse(in_array('test7', $cids), "Existing cache id test7 is not in cids array.");
     $this->assertFalse(in_array('test19', $cids), "Added cache id test19 is not in cids array.");
+    // Test with a long $cid and non-numeric array key.
+    $cids = array('key:key' => $long_cid);
+    $return = $backend->getMultiple($cids);
+    $this->assertEqual(300, $return[$long_cid]->data);
+    $this->assertTrue(empty($cids));
   }
 
   /**
