将PRIMARY KEY添加到大型InnoDB表的好方法是什么?


8

在使用InnoDB存储引擎的MySQL 5.5中,我有一个包含约3000万行的表。该表具有一个外键,该外键链接到具有约300万行的另一个表。

我想在较大的表中添加一个主键,但是不确定如何最好地做到这一点。我没有可用于此的现有列(或一组列),那么该如何处理?

我已经看到了一些对内部InnoDB记录ID的引用,但是没有找到它是否可以访问。

否则,也许我将需要转储并重新加载数据,并手动添加ID。

谢谢。


它们在表中的键组合自然是唯一的吗?如果是这样,则多列主键可能有意义。
Justin Dearing

不幸的是,不可能有这样的复合键。否则,我同意这是有道理的。我已经编辑了该帖子,以澄清这是不可能的。
Wodin 2011年

Answers:


7

这可能是错误的解决方法,但是..

你不能只是改变表的结构,

在表中添加主键列

然后...

编写一个快速脚本以遍历整个表格

向新列添加自动增量值?


2
谢谢你的建议。我想我必须将列添加为非主键,然后再将其转换为主键,但实际上我只是在对小表进行测试时意外发现,添加了AUTO_INCREMENT列(作为主键)自动填写ID。假设这只会给我一个错误,所以我认为这就是答案。
Wodin 2011年

如果数据库使用率很高,则可能需要在非关键表上对其进行测试,以确保它不会长时间锁定它
Patrick

@Patrick,感谢您的谨慎注意。该数据库当前未使用,我完全希望这可以长时间锁定该表。
Wodin

1
我做了ALTER TABLE blah ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;,花了2个小时18分钟:)在这段时间内,我没有尝试写表,但读取效果很好。
Wodin

1
@Wodin哇,这对于alter table命令来说是很长的时间。很高兴为您解决。
Patrick

3

这是我的处理方法:

  1. 创建具有所需结构的新表,其中包括带有WAUTO_INCREMENT的PRIMARY KEY以及可能包含另一个索引字段。
  2. 请停工以停止所有流量。
  3. 确认您拥有合法的数据备份。
  4. 利用AUTO INCREMENT创建ID,将现有表中的所有行复制到目标表中。*例如从origin_table插入到target_table(col1,col2等)SELECT(col1,col2等); *
  5. 测试新表中的数据是否正确。
  6. 重命名旧表origin_table_BAK。
  7. target_table重命名为origin_table。
  8. 冒烟测试您的应用程序。
  9. 重新开放。
  10. 下一次备份后,删除origin_table_BAK。

*注意:如果源表是InnoDB,将保留外键约束并在重命名后幸免。因此,您必须进行更改以补救该问题。


3
如果您需要实时进行操作,请在一个RENAME中执行步骤6和7,从而使其原子化。重命名表real_name TO旧,新TO real_name;
里克·詹姆斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.