5

这是我的数据库架构

+------------------+------------------+------+-----+---------------------+----------------+
| 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 auto increment on MySQL duplicate insert does not handle bulk inserts。我想做这样的事情:

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。

4

3 回答 3

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,没有间隙。

于 2012-11-10T01:43:44.347 回答
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)
于 2014-02-11T03:16:10.790 回答
-2

只需使用插入忽略。这将忽略任何由于重复键而失败的插入。其余的插入将很好地完成。

于 2012-11-10T03:57:07.897 回答