我有一个名为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;
但这似乎容易出错。
(如果还有另一种方法可以在不创建另一个表的情况下执行此操作,我也可以这样做。)
答案 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)
如果我插入了所有这些行,则不会因为重复或其他原因而被拒绝。
我将使用的方法是从id
向small
添加偏移值。假设id
中的small
值都是正值,我只会使用id
中large
的最大值作为偏移量。例如,如果id
中的最大large
值为142014
INSERT INTO large (id, ... )
SELECT id + 42014 AS new_id, ... FROM small ;
如果我想记录"映射",而我无法修改small
或large
,我会创建另一个表来保存两个值:
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;