这是我的数据库架构
+------------------+------------------+------+-----+---------------------+----------------+
| 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 :(得分:3)
阅读完其他文章之后,一种方法是使用批量插入的临时表。然后从临时表中选择行到我们的实际表中。此时将删除重复的行,实际表中的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,没有间隙。
答案 1 :(得分: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 ("0123456789");
SELECT MAX(id) FROM phone_numbers;
INSERT IGNORE INTO phone_numbers (phone_number) VALUES ("0123456789");
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)
答案 2 :(得分:-2)
只需使用INSERT IGNORE即可。这将忽略因重复键而失败的任何插入。其余的插页将会很好。