我有一张设计糟糕的桌子:
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
);
我之前认为它现在很糟糕的原因是因为现在我不能重用那个token
表,如果我想要一个与电子邮件或其他相关的令牌。我可以添加email_id
列,但是我需要丑陋的逻辑来确定令牌是分别用于用户还是电子邮件。
我希望对此设计进行规范化,以便我可以将一个token
表与任何user_id
或email_id
相关联,并user_token
和关系的email_token
数据透视表。
但我也在使用迁移,因此我无法重写我的架构。我需要使用数据库中的数据动态修改它。
我需要做以下事情:
user_token
和email_token
表(完整版) token.id
复制到user_token.token_id
列,并将token.user_id
值复制到user_token.user_id
列。复制需要在INSERT
语句中完成,因为user_token
表格是全新的,没有数据(TODO) token.user_id
列(完成) 第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
);
答案 0 :(得分:1)
如果您没有从令牌表中删除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
如果你想复制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
这会将它们复制到新表中。然后,您只需要通过简单的ALTER:
从令牌表中删除user_id和email_id列首先删除外键:
ALTER TABLE token DROP FOREIGN KEY user_id
然后删除栏目:
ALTER TABLE token DROP COLUMN user_id;
ALTER TABLE token DROP COLUMN email_id;