当我不想增加自动增量 ID 时,我遇到了问题。我知道使用 INSERT IGNORE 时自动增量 ID 会增加,所以我正在解决这个问题,但仍然出现我无法弄清楚的行为。
我正在构建一个规范化的交易表,在这个表中有一个名字列,它将有一个 transaction_first_names 的引用表。我的工作流程是,我将数据加载到非规范化的暂存表中,将暂存表中的值与引用表中的值进行比较,如果它们不存在于引用表中,则将数据从暂存表移动到规范化表中表。
我遇到的问题是,当我尝试将暂存表中的任何"new"值插入到引用表中时,它似乎以一种我无法解释的方式增加了引用表中的自动增量 ID。我通常不会对 id 感到强制症或吝啬,但作为一个持续的过程,我不希望 id 不断被咀嚼。
这是我的设置、链接和代码。正如您在第二个结果中看到的那样,最后插入的值的 ID 为 16,而目标是 ID 应为 9:
Runnable Example - http://rextester.com/KVMO89341
CREATE TABLE IF NOT EXISTS `transaction_first_names` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`first_name` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `u_first_name` (`first_name`)
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `transaction_stage` (
`transaction_id` BIGINT(20) UNSIGNED NOT NULL,
`first_name` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`transaction_id`),
INDEX `first_name` (`first_name`(191))
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;
TRUNCATE transaction_stage;
TRUNCATE transaction_first_names;
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3658822144, 'Michael');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3658825319, 'Pete');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3658828867, 'Robert');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3658865656, 'Martin');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3659080925, 'Charlews');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3659943769, 'Christopher');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3660191699, 'Robert');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3660192662, 'Errol');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3660194469, 'Frank');
INSERT INTO `transaction_stage` (`transaction_id`, `first_name`) VALUES (3660200483, 'Frank');
-- first select
SELECT DISTINCT st.first_name
FROM transaction_stage st
LEFT JOIN transaction_first_names f ON st.first_name <=> f.first_name
WHERE f.id IS NULL
AND st.first_name IS NOT NULL;
-- first insert
INSERT INTO transaction_first_names (`first_name`)
SELECT DISTINCT st.first_name
FROM transaction_stage st
LEFT JOIN transaction_first_names f ON st.first_name <=> f.first_name
WHERE f.id IS NULL
AND st.first_name IS NOT NULL;
-- second insert
INSERT INTO transaction_first_names (`first_name`)
VALUES ('Another name');
-- check autoincrement
SELECT * FROM transaction_first_names order by id asc;
DROP TABLE IF EXISTS transaction_first_names;
DROP TABLE IF EXISTS transaction_stage;
我试过在第一个插入语句中包装 select distinct,但没有成功。
最佳答案
啊,根据系统变量 innodb_autoinc_lock_mode
的设置方式,InnoDB 处理事情的方式有点不同。
For lock modes 1 or 2, gaps may occur between successive statements because for bulk inserts the exact number of auto-increment values required by each statement may not be known and overestimation is possible.
https://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html
关于mysql - 插入增加的自动增量值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44549628/