2012-11-10 17 views
2

這裏是我的數據庫架構如何在不增加重複項的auto_increment列的情況下執行批量mysql插入?

+------------------+------------------+------+-----+---------------------+----------------+ 
| Field   | Type    | Null | Key | Default    | Extra   | 
+------------------+------------------+------+-----+---------------------+----------------+ 
| phone_number  | varchar(64)  | NO | UNI | NULL    |    | 
| id    | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
+------------------+------------------+------+-----+---------------------+----------------+ 

我希望能夠在一次插入多個電話號碼(PHONE_NUMBER是一個獨特的密鑰),但我不想遞增AUTO_INCREMENT領域,如果我有重複。

如果我做INSERT INTO phone_numbers (phone_number) VALUES (%values%) ON DUPLICATE KEY UPDATE id=id; auto_increment將增加,即使重複。

此問題:prevent autoincrement on MYSQL duplicate insert不處理批量插入。我想要做這樣的事情:INSERT INTO phone_numbers (phone_number) SELECT '12345', '123456' FROM DUAL WHERE NOT EXISTS(SELECT phone_number FROM phone_numbers WHERE phone_number IN ('12345', '123456');DUAL表並沒有真正處理好多個值。

任何想法? MySQL 5.5。

+0

非常重要,爲什麼它不光滑R' – eggyal

+0

我很好奇你爲什麼關心auto_increment字段的增加。 –

+0

因爲我可以達到int無符號的天花板。是的,我知道我可以將它與「mediumint」或「bigint」相提並論,但如果我不需要,我寧願不去。我將處理比實際值更多的重複。 – Newtang

回答

3

在閱讀另一篇文章之後,一種方法是製作一個臨時表,您可以批量插入。然後選擇temp表中的行到我們的實際表中。重複的行將在此時被刪除,實際表中的auto_increment字段將是正確的。

CREATE TABLE PHONE_NUMBERS (id int(10) NOT NULL AUTO_INCREMENT, phone_number varchar(64), primary key (id), unique(phone_number)); 

CREATE TEMPORARY TABLE TMP_PHONE_NUMBERS (phone_number varchar(64), unique(phone_number)); 

' bulk insert 
INSERT INTO tmp_phone_numbers (phone_number) VALUES (%values%) 

' remove phone numbers that already exist. This will create a unique 
' set of phone numbers that do not exist in the real table. 
DELETE FROM tmp_phone_numbers WHERE phone_number in (SELECT phone_number from phone_numbers); 

' copy into real table 
INSERT INTO phone_numbers (phone_number) SELECT phone_number FROM tmp_phone_numbers; 

' Temp table is dropped when your connection is closed. 

這裏是另一種選擇:

如果你知道你不會打在首次批量裝載或任何後續的批量加載INT(10),可以使用INSERT INTO phone_numbers (phone_number) VALUES (%values%) ON DUPLICATE KEY UPDATE id=id;將留在ID領域的空白。但是在完成批量加載後,您可以刪除ID列,然後重新添加它,這將重新創建您的所有ID,沒有空白。

+0

我想我明白你要去的地方。我可以爲您查詢示例嗎? – Newtang

+0

建議您爲此使用'TEMPORARY TABLE'。您可能還想在插入之前執行「phone_numbers」的查找(我猜這有點重要?)。 – eggyal

+0

@eggyal如果他能確保所有這些都是通過單一連接完成的,我同意。 –

-2

只需使用INSERT IGNORE即可。這將忽略任何由於重複鍵而失敗的插入。其餘的插入將會很好。

+0

這不是關於由於重複鍵而失敗的插入。 – Newtang

+0

我知道。但INSERT IGNORE只會插入新記錄,不會自動增加任何現有記錄。它甚至不會觸及現有記錄,從而解決了所述問題。 –

0

由於INSERT IGNORE確實會增加表上的自動增量計數器(即使不對數據進行任何更改),一個簡單的解決方法是通過利用來恢復事務結束時的自動增量值當試圖強制值過低總是選擇一個整數比目前最高的AI值時,發動機的邏輯:

ALTER TABLE phone_numbers AUTO_INCREMENT = 0; 

這樣做不需要一個表重建,並且可以作爲測試如下:

SELECT MAX(id) FROM phone_numbers; 
INSERT IGNORE INTO phone_numbers (phone_number) VALUES (""); 
SELECT MAX(id) FROM phone_numbers; 
INSERT IGNORE INTO phone_numbers (phone_number) VALUES (""); 
SELECT MAX(id) FROM phone_numbers; 
ALTER TABLE phone_numbers AUTO_INCREMENT = 1; 
INSERT IGNORE INTO phone_numbers (phone_number) VALUES ("1000000000"); 
SELECT MAX(id) FROM phone_numbers; 

+---------+ 
| MAX(id) | 
+---------+ 
| NULL | 
+---------+ 
1 row in set (0.00 sec) 

Query OK, 1 rows affected (0.00 sec) 

+---------+ 
| MAX(id) | 
+---------+ 
|  1 | 
+---------+ 
1 row in set (0.00 sec) 

Query OK, 0 rows affected (0.00 sec) 

+---------+ 
| MAX(id) | 
+---------+ 
|  1 | 
+---------+ 
1 row in set (0.00 sec) 

Query OK, 1 rows affected (0.33 sec) 
Records: 1 Duplicates: 0 Warnings: 0 

Query OK, 0 rows affected (0.00 sec) 

+---------+ 
| MAX(id) | 
+---------+ 
|  2 | 
+---------+ 
1 row in set (0.00 sec) 
相關問題