用新的外键替换列值的方法?

时间:2019-03-29 21:02:13

标签: mysql sql foreign-keys

我有一个大表(数百万行),我想用SELECT setval('my_sequence_name', max(mycolumn)) FROM myschema.mytable; 替换VARCHAR列中的所有值,这将是指向新表的外键保留所有INT值。如果重要的话,VARCHAR值是唯一的。

此刻,我可以使用以下命令有效地创建外部表:

VARCHAR

但是我第一次替换VARCHAR列的基本尝试效率极低,并且每行花费几秒钟,这显然不可行(INSERT INTO `messages` (`message`) SELECT `message` FROM `history`; 可以进行测试)。

LIMIT

感觉我应该能够完全用SQL来完成此过程,而不是依赖PHP,希望这也是一种有效的方法。

2 个答案:

答案 0 :(得分:3)

您可以使用UPDATE ... JOIN查询来让您的RDBMS一次完成繁重的工作,而不是使用PHP循环:

UPDATE history h
INNER JOIN messages m ON m.message = h.message
SET h.message = m.id

这假定表messages已经送入。为了获得更好的性能,由于您声明列message中的值是唯一的,因此您可能想在UNIQUE上创建messages(messsage)约束。

答案 1 :(得分:1)

您必须使用php吗?因为您正在: 1)一个请求带来100行 2)对于每一行,一个请求携带另一个表的ID,然后另一个请求更新原始表。而且我认为原始表大于100行。

您不能直接在数据库内部进行操作吗?如果varchar值是唯一的,而您想要的只是将它们放在单独的表中,则可以像您一样填充新表,但还要指定id,这将很方便地与原始表的id相同:< / p>

INSERT INTO `messages` (`id`, `message`) SELECT `id`, `message` FROM `history`;

然后,创建一个新的INT列,该列将保存外键:

ALTER TABLE history ADD message_id INT;

然后,填充列:

UPDATE history SET message_id = id;

然后删除varchar列:

ALTER TABLE history DROP message;

您现在可以添加约束,以指示message_id是外键:

ALTER TABLE history ADD CONSTRAINT fk_message_id FOREIGN KEY message_id REFERENCES messages(id);

通过这种方式,您只需进行两次迭代:一次用于填充新表,另一次用于设置新列。