diff --git includes/database/pgsql/schema.inc includes/database/pgsql/schema.inc
index 30f12ef..3f55e80 100644
--- includes/database/pgsql/schema.inc
+++ includes/database/pgsql/schema.inc
@@ -129,7 +129,8 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
     }
     if (isset($table['unique keys']) && is_array($table['unique keys'])) {
       foreach ($table['unique keys'] as $key_name => $key) {
-        $sql_keys[] = 'CONSTRAINT ' . $this->prefixNonTable($name, $key_name, 'key') . ' UNIQUE (' . implode(', ', $key) . ')';
+        $info = $this->getTableOrObjectName($name, $key_name, 'key');
+        $sql_keys[] = 'CONSTRAINT ' . $info['name'] . ' UNIQUE (' . implode(', ', $key) . ')';
       }
     }
 
@@ -416,9 +417,9 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
   }
 
   public function indexExists($table, $name) {
+    $info = $this->getTableOrObjectName($table, $name, 'idx');
     // Details http://www.postgresql.org/docs/8.3/interactive/view-pg-indexes.html
-    $index_name = '{' . $table . '}_' . $name . '_idx';
-    return (bool) $this->connection->query("SELECT 1 FROM pg_indexes WHERE indexname = '$index_name'")->fetchField();
+    return (bool) $this->connection->query('SELECT 1 FROM pg_indexes WHERE schemaname = :schema AND indexname = :name', array(':schema_name' => $info['schema'], ':name' => $info['name']))->fetchField();
   }
 
   /**
@@ -430,8 +431,8 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
    *   The name of the constraint (typically 'pkey' or '[constraint]_key').
    */
   protected function constraintExists($table, $name) {
-    $constraint_name = '{' . $table . '}_' . $name;
-    return (bool) $this->connection->query("SELECT 1 FROM pg_constraint WHERE conname = '$constraint_name'")->fetchField();
+    $info = $this->getTableOrObjectName($table, $name);
+    return (bool) $this->connection->query('SELECT 1 FROM pg_constraint AS c INNER JOIN pg_namespace AS n ON n.oid = c.connamespace WHERE c.conname = :name  AND n.nspname = :schema_name;', array(':schema_name' => $info['schema'], ':name' => $info['name']))->fetchField();
   }
 
   public function addPrimaryKey($table, $fields) {
@@ -442,7 +443,7 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add primary key to table %table: primary key already exists.", array('%table' => $table)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . implode(',', $fields) . ')');
+    $this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT PRIMARY KEY (' . implode(',', $fields) . ')');
   }
 
   public function dropPrimaryKey($table) {
@@ -450,7 +451,8 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $this->prefixNonTable($table, 'pkey'));
+    $info = $this->getTableOrObjectName($table, 'pkey');
+    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT ' . $info['name']);
     return TRUE;
   }
 
@@ -462,7 +464,8 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '" UNIQUE (' . implode(',', $fields) . ')');
+    $info = $this->getTableOrObjectName($table, $name, 'key');
+    $this->connection->query('ALTER TABLE {' . $table . '} ADD CONSTRAINT "' . $info['name'] . '" UNIQUE (' . implode(',', $fields) . ')');
   }
 
   public function dropUniqueKey($table, $name) {
@@ -470,7 +473,8 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $this->prefixNonTable($table, $name, 'key') . '"');
+    $info = $this->getTableOrObjectName($table, $name, 'key');
+    $this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT "' . $info['name'] . '"');
     return TRUE;
   }
 
@@ -490,7 +494,8 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
       return FALSE;
     }
 
-    $this->connection->query('DROP INDEX ' . $this->prefixNonTable($table, $name, 'idx'));
+    $info = $this->getTableOrObjectName($table, $name, 'idx');
+    $this->connection->query('DROP INDEX ' . $info['name']);
     return TRUE;
   }
 
@@ -573,7 +578,8 @@ class DatabaseSchema_pgsql extends DatabaseSchema {
   }
 
   protected function _createIndexSql($table, $name, $fields) {
-    $query = 'CREATE INDEX "' . $this->prefixNonTable($table, $name, 'idx') . '" ON {' . $table . '} (';
+    $info = $this->getTableOrObjectName($table, $name, 'idx');
+    $query = 'CREATE INDEX "' . $info['nane'] . '" ON {' . $table . '} (';
     $query .= $this->_createKeySql($fields) . ')';
     return $query;
   }
diff --git includes/database/schema.inc includes/database/schema.inc
index e57c94b..a2b91fa 100644
--- includes/database/schema.inc
+++ includes/database/schema.inc
@@ -224,13 +224,21 @@ abstract class DatabaseSchema implements QueryPlaceholderInterface {
   /**
    * Create names for indexes, primary keys and constraints.
    *
-   * This prevents using {} around non-table names like indexes and keys.
+   * This should be used instead of {} around non-table names like indexes and
+   * keys.
+   *
+   * @return
+   *   A keyed array containing the unique name to use, name, and the associated
+   *   schema, schema.
    */
-  function prefixNonTable($table) {
+  protected function getTableOrObjectName($table) {
     $args = func_get_args();
     $info = $this->getPrefixInfo($table);
     $args[0] = $info['table'];
-    return implode('_', $args);
+    return array(
+      'schema' => $info['schema'],
+      'name' => implode('__', $args),
+    );
   }
 
   /**
@@ -697,4 +705,3 @@ class DatabaseSchemaObjectDoesNotExistException extends Exception {}
 /**
  * @} End of "defgroup schemaapi".
  */
-
diff --git includes/database/sqlite/schema.inc includes/database/sqlite/schema.inc
index 11ecd88..ebe2dc5 100644
--- includes/database/sqlite/schema.inc
+++ includes/database/sqlite/schema.inc
@@ -52,15 +52,17 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
    */
   protected function createIndexSql($tablename, $schema) {
     $sql = array();
-    $info = $this->getPrefixInfo($tablename);
+    $table_info = $this->getPrefixInfo($tablename);
     if (!empty($schema['unique keys'])) {
       foreach ($schema['unique keys'] as $key => $fields) {
-        $sql[] = 'CREATE UNIQUE INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $key . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . "); \n";
+        $index_info = $this->getTableOrObjectName($tablename, $key, 'key');
+        $sql[] = 'CREATE UNIQUE INDEX ' . $index_info['schema'] . '.' . $index_info['name'] . ' ON ' . $table_info['table'] . ' (' . $this->createKeySql($fields) . "); \n";
       }
     }
     if (!empty($schema['indexes'])) {
       foreach ($schema['indexes'] as $key => $fields) {
-        $sql[] = 'CREATE INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $key . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . "); \n";
+        $index_info = $this->getTableOrObjectName($tablename, $key, 'idx');
+        $sql[] = 'CREATE INDEX ' . $index_info['schema'] . '.' . $index_info['name'] . ' ON ' . $table_info['table'] . ' (' . $this->createKeySql($fields) . "); \n";
       }
     }
     return $sql;
@@ -457,10 +459,21 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
       }
     }
     foreach ($indexes as $index) {
-      $name = $index['name'];
-      // Get index name without prefix.
-      $index_name = substr($name, strlen($info['table']) + 1);
-      $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $name . ')');
+      // If the index matches our naming convention, extract its internal name.
+      if (preg_match('/^idx__' . preg_quote($info['table']) . '__(.+)$/', $index['name'], $matches)) {
+        $index_name = $matches[1];
+      }
+      // Or the index could match our previous naming convention; extract its
+      // internal name, it will be recreated using the new name.
+      else if (preg_match('/^' . preg_quote($info['table']) . '_(.+)$/', $index['name'], $matches)) {
+        $index_name = $matches[1];
+      }
+      else {
+        continue;
+      }
+
+      // Get the columns participating in the index.
+      $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $index['name'] . ')');
       foreach ($result as $row) {
         $schema[$index['schema_key']][$index_name][] = $row->name;
       }
@@ -573,9 +586,8 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
   }
 
   public function indexExists($table, $name) {
-    $info = $this->getPrefixInfo($table);
-
-    return $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $info['table'] . '_' . $name . ')')->fetchField() != '';
+    $info = $this->getTableOrObjectName($table, $name, 'idx');
+    return $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $info['nane'] . ')')->fetchField() != '';
   }
 
   public function dropIndex($table, $name) {
@@ -583,17 +595,24 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
       return FALSE;
     }
 
-    $info = $this->getPrefixInfo($table);
-
-    $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name);
+    $info = $this->getTableOrObjectName($table, $name, 'idx');
+    $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['name']);
     return TRUE;
   }
 
+  /**
+   * Helper function: check if a unique key exists.
+   */
+  protected function uniqueKeyExists($table, $name) {
+    $info = $this->getTableOrObjectName($table, $name, 'key');
+    return $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $info['nane'] . ')')->fetchField() != '';
+  }
+
   public function addUniqueKey($table, $name, $fields) {
     if (!$this->tableExists($table)) {
       throw new DatabaseSchemaObjectDoesNotExistException(t("Cannot add unique key %name to table %table: table doesn't exist.", array('%table' => $table, '%name' => $name)));
     }
-    if ($this->indexExists($table, $name)) {
+    if ($this->uniqueKeyExists($table, $name)) {
       throw new DatabaseSchemaObjectExistsException(t("Cannot add unique key %name to table %table: unique key already exists.", array('%table' => $table, '%name' => $name)));
     }
 
@@ -605,13 +624,12 @@ class DatabaseSchema_sqlite extends DatabaseSchema {
   }
 
   public function dropUniqueKey($table, $name) {
-    if (!$this->indexExists($table, $name)) {
+    if (!$this->uniqueKeyExists($table, $name)) {
       return FALSE;
     }
 
-    $info = $this->getPrefixInfo($table);
-
-    $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name);
+    $info = $this->getTableOrObjectName($table, $name, 'key');
+    $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['name']);
     return TRUE;
   }
 
diff --git modules/simpletest/tests/schema.test modules/simpletest/tests/schema.test
index 1dfa445..d0196cf 100644
--- modules/simpletest/tests/schema.test
+++ modules/simpletest/tests/schema.test
@@ -382,4 +382,91 @@ class SchemaTestCase extends DrupalWebTestCase {
 
     db_drop_field($table_name, $field_name);
   }
+
+  /**
+   * Test corner cases of the Schema support.
+   */
+  protected function testSchemaCornerCases() {
+    // We should be able to create a table without a primary key.
+    $exception = FALSE;
+    try {
+      db_create_table('test_non_primary_key', array(
+        'fields' => array(
+          'id' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+        ),
+        'indexes' => array(
+          'id' => array('id'),
+        )
+      ));
+    }
+    catch (Exception $e) {
+      $exception = TRUE;
+      $this->exceptionHandler($e);
+    }
+    $this->assertFalse($exception, t('The creation of a table without a primary key succeeded.'));
+
+    // We should not be able to create a table without columns.
+    $exception = FALSE;
+    try {
+      db_create_table('test_empty_columns', array(
+        'fields' => array(),
+      ));
+    }
+    catch (Exception $e) {
+      $exception = TRUE;
+    }
+    $this->assertTrue($exception, t('The creation of a table without columns triggered an exception.'));
+
+    // We should be able to create two tables sharing the same index name.
+    $exception = FALSE;
+    try {
+      db_create_table('test_index_1', array(
+        'fields' => array(
+          'name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE),
+        ),
+        'indexes' => array(
+          'name' => array('name'),
+        )
+      ));
+      db_create_table('test_index_2', array(
+        'fields' => array(
+          'name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE),
+        ),
+        'indexes' => array(
+          'name' => array('name'),
+        )
+      ));
+    }
+    catch (Exception $e) {
+      $exception = TRUE;
+      $this->exceptionHandler($e);
+    }
+    $this->assertFalse($exception, t('The creation of two tables sharing the same index name succeeded.'));
+
+    // We should be able to create a table and an index sharing the same name.
+    $exception = FALSE;
+    try {
+      // A table name 'test' has an index named 'field'. Does that collide with
+      // a table named 'test_field'?
+      db_create_table('test', array(
+        'fields' => array(
+          'field' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE),
+        ),
+        'indexes' => array(
+          'field' => array('field'),
+        )
+      ));
+      db_create_table('test_field', array(
+        'fields' => array(
+          'id' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
+        ),
+      ));
+    }
+    catch (Exception $e) {
+      $exception = TRUE;
+      $this->exceptionHandler($e);
+    }
+    $this->assertFalse($exception, t('The creation of a table and an index sharing the same name succeeded.'));
+
+  }
 }
diff --git modules/system/system.install modules/system/system.install
index eb6d017..b7d8ba2 100644
--- modules/system/system.install
+++ modules/system/system.install
@@ -2973,6 +2973,21 @@ function system_update_7069() {
 }
 
 /**
+ * Recreate all the tables on SQLite, to account for changes in the naming convention of indexes.
+ */
+function system_update_7070() {
+  if (Database::getConnection()->databaseType() == 'sqlite') {
+    foreach (drupal_get_schema() as $table_name => $table_specification) {
+      // Apply a NULL operation on the table will force SQLite to recreate it.
+      $first_field_specification = reset($table_specification['fields']);
+      $first_field_name = key($table_specification['fields']);
+      db_change_field($table_name, $first_field_name, $first_field_name, $first_field_specification);
+    }
+  }
+}
+
+
+/**
  * @} End of "defgroup updates-6.x-to-7.x"
  * The next series of updates should start at 8000.
  */
