2010-08-19 32 views
1

我在MySQL中創建表的命令是保持順序主鍵在錯誤插入

CREATE TABLE `map` (
    `id` int(4) AUTO_INCREMENT NOT NULL, 
    `city` varchar(100) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE = InnoDB; 

CREATE UNIQUE INDEX `map_city_idx` 
    ON `map` 
    (`city`); 

初值,如:

id(1),city('Banda Aceh') 
id(2),city('Medan') 

下一個插入的城市(「棉蘭」),所以它的錯誤因爲城市列是獨一無二的。接下來的插入是城市( '明古魯'),決賽桌的結果是

id(1), city('Banda Aceh') 
id(2), city('Medan') 
id(4), city('Bengkulu') 

這不是ID(3),但ID(4)代替。那麼,我怎麼能保持順序主鍵事件,即使之前有插入錯誤?

id(1), city('Banda Aceh') 
id(2), city('Medan') 
id(3), city('Bengkulu') 
+2

爲什麼你需要你的密鑰是連續的?無論如何,如果/當您執行刪除操作時,您的ID中都會有「空白」,所以您不應該指望您的密鑰是連續的。 – 2010-08-19 17:58:45

回答

0

看起來像InnoDB的行爲。 InnoDB回滾事務,但自動增量密鑰無法恢復,因爲它可能被其他人使用。這在MyISAM表中不會發生,但InnoDB有能力阻止它使用事務。我會用php寫這個,但是你可以用你想要的任何語言重複它:

mysql_query('START TRANSACTION'); 
//query if it exists and lock the record 
$r = mysql_query('SELECT id FROM map WHERE city="Medan" FOR UPDATE'); 
if(mysql_num_rows($r)>0){ 
    //already exists 
    // there are better ways to do this, buy you got the idea. 
    list($id) = mysql_fetch_row($id); 
    mysql_query('ROLLBACK'); // release the lock 
}else{ 
    // does not exists - insert it 
    mysql_query('INSERT INTO map(city) VALUES("Medan")'); 
    $id = mysql_insert_id(); 
    mysql_query('COMMIT'); //commit and release the lock 
} 
//... here $id will be id of 'Medan' city regardless if it is inserted now 
// or it is duplicate and there will be no autoincrement key holes