简体   繁体   English

MySQL:使用不同的架构将数据从一个表移动到另一个表

[英]MySQL: Move data from one table to another with different schema

I have a table with a bad design: 我的桌子设计不好:

CREATE TABLE token (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    user_id INT(10) UNSIGNED NOT NULL,

    token VARCHAR(191) NOT NULL,
    expiration TIMESTAMP NOT NULL,

    created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL DEFAULT NULL,

    PRIMARY KEY (id),
    FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE
);

The reason I see it as bad now even though it worked well before is because now I cannot reuse that token table if I want a token related to an email or something else. 我现在认为它很糟糕,即使它以前运行良好,也是因为现在,如果我想要与电子邮件或其他内容相关的令牌,就无法重用该token表。 I could just add email_id column but then I would need ugly logic to determine if the token is meant for a user or an email, respectively. 我可以只添加email_id列,但是然后我需要丑陋的逻辑来确定令牌是分别用于用户还是电子邮件。

I want to normalize this design such that I can have a single token table that isn't coupled to any user_id or email_id , and have user_token and email_token pivot tables for the relations. 我想规范化这种设计,以便可以有一个不与任何user_idemail_id耦合的单个token表,并具有用于关系的user_tokenemail_token数据透视表。

But I am also using migrations so I can't just rewrite my schema. 但是我也在使用迁移,所以我不能只重写我的架构。 I need to modify this on the fly with data present in the database. 我需要使用数据库中存在的数据即时对此进行修改。

I need to do the following: 我需要执行以下操作:

  1. Create new user_token and email_token tables (COMPLETE) 创建新的user_tokenemail_token(已完成)
  2. Copy token.id to user_token.token_id column, and copy token.user_id value to user_token.user_id column. token.id复制到user_token.token_id列,并将token.user_id值复制到user_token.user_id列。 The copying needs to be done in an INSERT statement since the user_token table will be brand new with no data (TODO) 复制需要在INSERT语句中完成,因为user_token表将是全新的,没有数据(TODO)
  3. Remove token.user_id column (COMPLETE) 删除token.user_id(完整)

Step 2 is the part I need help on. 步骤2是我需要帮助的部分。 Any help would be appreciated to write that query. 任何帮助将不胜感激写该查询。

This is what the new schema will look like if it helps to create a query for step 2: 如果新模式有助于为步骤2创建查询,则新模式将如下所示:

CREATE TABLE token (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,

    token VARCHAR(191) NOT NULL,
    expiration TIMESTAMP NOT NULL,

    created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL DEFAULT NULL,

    PRIMARY KEY (id)
);

CREATE TABLE user_token (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    user_id INT(10) UNSIGNED NOT NULL,
    token_id INT(10) UNSIGNED NOT NULL,

    created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL DEFAULT NULL,

    PRIMARY KEY (id),
    FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE,
    FOREIGN KEY (token_id) REFERENCES token (id) ON DELETE CASCADE
);

CREATE TABLE email_token (
    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    email_id INT(10) UNSIGNED NOT NULL,
    token_id INT(10) UNSIGNED NOT NULL,

    created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP NULL DEFAULT NULL,

    PRIMARY KEY (id),
    FOREIGN KEY (email_id) REFERENCES user (id) ON DELETE CASCADE,
    FOREIGN KEY (token_id) REFERENCES token (id) ON DELETE CASCADE
);

IF you haven't delete token.user_id and token.email_id columns from token table, then you can copy them by using a simple INSERT: 如果您尚未从令牌表中删除token.user_id和token.email_id列,则可以使用简单的INSERT复制它们:

INSERT INTO user_token (user_id, token_id)
SELECT user_id, id
FROM token

INSERT INTO email_token (email_id, token_id)
SELECT email_id, id
FROM token

if you want to copy created_at, updated_at, and deleted_at columns along with them, you could just add them into the query: 如果要与它们一起复制created_at,updated_at和Deleted_at列,则可以将它们添加到查询中:

INSERT INTO user_token (user_id, token_id, created_at, updated_at, deleted_at)
SELECT user_id, id, created_at, updated_at, deleted_at
FROM token

INSERT INTO email_token (email_id, token_id, created_at, updated_at, deleted_at)
SELECT email_id, id, created_at, updated_at, deleted_at
FROM token

this will copy them into the new tables. 这会将它们复制到新表中。 Then, you only need to delete user_id and email_id columns from token table by a simple ALTER : 然后,您只需要通过简单的ALTER从令牌表中删除user_id和email_id列:

FIRST DELETE FOREIGN KEY: 第一个删除外键:

ALTER TABLE token DROP FOREIGN KEY user_id

THEN DELETE THE COLUMNS: 然后删除列:

ALTER TABLE token DROP COLUMN user_id;
ALTER TABLE token DROP COLUMN email_id;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM