我正在清理一个随着时间的推移而变得混乱的mysql数据库。清理是增量的(也就是说我不想一次迁移所有表)。
我希望尽可能避免对旧表进行破坏性编辑。例如,我将表文件夹重命名为 decomissioned_folders ,然后创建一个新的文件夹表,可以将相应的记录迁移到该表中,而不会影响旧表。
此数据库中有很多表,其中一个是表用户。数据库中的许多其他表具有指向表用户的外键。
我想知道:
如果我将表用户重命名为 decomissioned_users ,然后创建一个新的用户表并填充它,那么最好的处理方法是什么用外键?对于数据库中现在包含指向旧 decomissioned_users 表的外键的每个表,是否有(简单)方法更新这些外键以指向新的用户表而不是?
(注意,id的值在表之间不会改变,因此外键的值将在表之间保持有效。)
答案 0 :(得分:2)
有一种简单的方法,但它涉及丢弃旧的外键并创建新的外键。
这是一个演示:
mysql> create table foo (id serial primary key);
mysql> create table bar (foo_id bigint unsigned, foreign key (foo_id) references foo(id));
重命名表后,外键引用会自动更新,以跟随重命名的表:
mysql> rename table foo to old_foo;
mysql> show create table bar\G
*************************** 1. row ***************************
Table: bar
Create Table: CREATE TABLE `bar` (
`foo_id` bigint(20) unsigned DEFAULT NULL,
KEY `foo_id` (`foo_id`),
CONSTRAINT `bar_ibfk_1` FOREIGN KEY (`foo_id`) REFERENCES `old_foo` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
创建新表后:
mysql> create table foo like old_foo;
我们可以通过以下方式重新定义外键:
mysql> alter table bar
drop foreign key bar_ibfk_1,
add foreign key (foo_id) references foo(id);
现在该表引用了新表:
mysql> show create table bar\G
*************************** 1. row ***************************
Table: bar
Create Table: CREATE TABLE `bar` (
`foo_id` bigint(20) unsigned DEFAULT NULL,
KEY `foo_id` (`foo_id`),
CONSTRAINT `bar_ibfk_2` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
如果您有许多外键,可以通过查询INFORMATION_SCHEMA,表TABLE_CONSTRAINTS和KEY_COLUMN_USAGE来发现它们的列表。通过此元数据,您可以构建ALTER TABLE语句以更改外键。