mysql - 插入增加的自动增量值

标签 mysql

当我不想增加自动增量 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/

相关文章:

mysql - 迭代数据集以更新 mysql 中的列

mysql - TYPO3:删除没有 pid 的页面记录

mysql - 这个更新查询有什么问题?我得到 "no records changed"

javascript - 使用 javascript 从数据库中删除

将图像文件插入mysql表的PHP脚本

mysql - 第 1 行 'contact_no' 列的值超出范围

mysql - 如何获得日期时间范围的总小时数

mysql - 无法使用 DBeaver 连接到 MariaDB

mysql - 向 mysql 数据库中的所有表添加列(未知表名)

mysql - MariaDB 更新报错 inner join 和 select