将小表插入大表中,跟踪ID

时间:2015-05-26 16:05:15

标签: mysql sql

我有一个名为small的表,其中包含三列:(id, first_name, last_name)。我有一个名为large的更大的表,它还包含三列:(id, first_name, last_name)。两个id列都是auto_increment。我想将small中的每一行插入large,但我也想跟踪ID号的变化情况。也就是说,我想创建一个结构为(small_id, large_id)的辅助表。

有干净的方法吗?我不想修改任何一个表的架构。插入后我也无法进行连接,因为无法保证(first_name, last_name)是唯一的。我甚至不确定如何干净利落地正确获取这些插入的行在large中获取的新ID号。目前我所拥有的是:

INSERT INTO large (first_name, last_name) SELECT first_name, last_name FROM small;
SET @cnt = (SELECT COUNT(*) FROM small);
SELECT id FROM large ORDER BY id DESC LIMIT @cnt;

但这似乎容易出错。

(如果还有另一种方法可以在不创建另一个表的情况下执行此操作,我也可以这样做。)

3 个答案:

答案 0 :(得分:1)

如果您只打算一次并且不间断,那么您可以将large.id自动增量种子设置为大于任何其他large.id的数字:

ALTER TABLE tbl AUTO_INCREMENT = 1000001;

然后运行脚本以插入从小到大的记录:

INSERT INTO large (first_name, last_name)
SELECT s.first_name, s.last_name FROM small s ORDER BY s.id;

然后将large.id自动增量种子设置为大于任何其他large.id的数字:

ALTER TABLE tbl AUTO_INCREMENT = 2000001;

现在您为表格小的值保留范围[1000001,2000000]。 从small.id到large.id的转换非常简单:

large.id = small.id + 1000000

答案 1 :(得分:0)

如果我插入了所有这些行,则不会因为重复或其他原因而被拒绝。

我将使用的方法是从idsmall添加偏移值。假设id中的small值都是正值,我只会使用idlarge的最大值作为偏移量。例如,如果id中的最大large值为142014

 INSERT INTO large (id, ... )
 SELECT id + 42014 AS new_id, ... FROM small ;

如果我想记录"映射",而我无法修改smalllarge,我会创建另一个表来保存两个值:

 SELECT id AS old_id, id + 42014 AS new_id FROM small

答案 2 :(得分:0)

正如其他人在评论中指出的那样,您应该更改large表的表格结构,以便直接包含small.id列值和INSERT ... SELECT ... FROM small

如果由于某种原因无法做到这一点,则需要创建一个脚本来传输记录(伪代码):

CREATE TABLE IF NOT EXISTS large_small(small_id INT UNSIGNED, large_id INT UNSIGNED);

SELECT MAX(small_id) AS max_small_id FROM large_small;
rows = SELECT * FROM small WHERE id > :max_small_id;
foreach row in rows:
    START TRANSACTION;
    INSERT INTO large(first_name, last_name) VALUES(row.first_name, row.last_name);
    INSERT INTO large_small(small_id, large_id) VALUES(row.id, LAST_INSERT_ID());
    COMMIT;