根据现有列数据设置外键值

时间:2016-04-05 12:27:13

标签: mysql foreign-keys database-normalization

我正在将旧的(非标准化)数据库迁移到新版本。

现在我有这个中间结果:

    CREATE TABLE recipient(
        id int NOT NULL AUTO_INCREMENT,
        email VARCHAR(255),
        PRIMARY KEY (id),
        UNIQUE INDEX (`email`),
    ) ENGINE=INNODB;

    CREATE TABLE comment(
        # Right now this is always NULL:
        fk_recipient INT,
        # Temporary solution. Note that this field is NOT UNIQUE:
        tmp_email VARCHAR(255) NOT NULL,
        # ...
        FOREIGN KEY (`fk_recipient`) REFERENCES recipient(id);
    ) ENGINE=INNODB;

两个表都填充了正确的数据:

  • tmp_email中右fk_recipient = nullcomment的一百万条评论(注意:电子邮件不是唯一的)
  • recipient中的数十万封UNIQUE电子邮件地址。

我需要做什么:

我希望摆脱comment.tmp_email列,而是将comment.fk_recipient指向表recipient中的相应行。

我当前的方法(使用PHP):

  1. 获取所有评论
  2. 遍历所有评论:
    • recipient表格
    • 中查找右侧行
    • 设置正确的外键
  3. ... DROP COLUMN tmp_email
  4. 这需要永远,让我想知道是否没有本地MySQL方法可以做到这一点?

1 个答案:

答案 0 :(得分:1)

以下解决方法将完成此任务:

  1. comment.tmp_email上创建临时外键:

    ALTER TABLE comment
        ADD CONSTRAINT `tmpMailKey` FOREIGN KEY (`tmp_email`)
        REFERENCES `recipient`(`email`);
  2. 加入临时密钥上的两个表并使用该信息设置真正的外键:

    UPDATE comment c
    INNER JOIN recipient r
    ON
            c.tmp_email = r.email
        AND c.tmp_email IS NOT NULL
    SET c.fk_recipient = r.id;
  3. 摆脱临时外键(以及tmp列):

    ALTER TABLE `udw_v3`.`travelogue_guestbookentry`
        DROP COLUMN `tmp_email`,
        DROP INDEX `tmpMailKey`,
        DROP FOREIGN KEY `tmpMailKey`;