我知道如何使用create new_table like old_table
复制表格,但是这并不会复制外键约束。我还可以对来自show create table old_table
的结果进行字符串操作(使用正则表达式替换表名和外键约束名),但那似乎容易出错。是否有更好的方法复制一个表的结构,包括外键?
我知道如何使用create new_table like old_table
复制表格,但是这并不会复制外键约束。我还可以对来自show create table old_table
的结果进行字符串操作(使用正则表达式替换表名和外键约束名),但那似乎容易出错。是否有更好的方法复制一个表的结构,包括外键?
create table like
之后准备ALTER TABLE ...
语句,基于以下信息:SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME LIKE '<table_name>'
AND TABLE_SCHEMA = '<db_name>'
AND REFERENCED_TABLE_NAME IS NOT NULL;
如果可以使用一点辅助脚本,你可以利用SHOW CREATE TABLE
的几行代码来实现(以下是PHP示例,但概念适用于任何语言):
// Get the create statement
$retrieve = "SHOW CREATE TABLE <yourtable>";
$create = <run the $retrieve statement>
// Isolate the "Create Table" index
$create = $create['Create Table'];
// Replace old table name with new table name everywhere
$create = preg_replace("/".$newname."/", $oldname, $create);
// You may need to rename foreign keys to prevent name re-use error.
// See https://dev59.com/wuo6XIcBkEYKwwoYPR_f
$create = preg_replace("/FK_/", "FK_TEMP_", $create);
// Create the new table
<run the $create statement>
这不是非常优雅,但目前为止它可以工作。我在测试环境中做这个,所以把它放在我的 setUp()
方法中。
TEMPORARY
表和其他东西也会出现问题。Wrikken 提到的解决方案是一个不错的方法,但是你需要至少再进行一次查找以获取关于 UPDATE
和 DELETE
规则的信息。SELECT *
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE TABLE_NAME LIKE '<table_name>'
AND CONSTRAINT_SCHEMA = '<db_name>';
mysqldump
转储数据库->你会得到file.sql
file.sql
Adminer
和mysqldump
都有选择特定表格的选项,因此您不必导出整个数据库。如果只需要结构而不需要数据,请在mysqldump
中使用-d
选项或在Adminer
中单击该选项。如果您只想清空您的表格,您可以将所有相关数据复制到副本表中。然后清除并复制回去。结果是,您保留了您的外键。
CREATE TABLE IF NOT EXISTS t_copy LIKE t_origin;
INSERT INTO t_copy
SELECT t_origin.*
FROM t_origin;
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE t_origin;
INSERT INTO t_origin
SELECT t_copy.*
FROM t_copy;
DROP TABLE t_copy;
SET FOREIGN_KEY_CHECKS = 1;
mysqldump -h ${host_ip} -u root -p${some_password} ${some_database} ${some_table} > some_filename
sed -i -r -e 's@KEY `([a-zA-Z0-9_]*)`@KEY `\1_1`@g' -e 's@CONSTRAINT `([a-zA-Z0-9_]*)`@CONSTRAINT `\1_1`@g' some_filename
mysql -h ${host_ip} -u root -p${some_password} ${some_new_database} < some_filename
这也适用于新的数据库实例,但是'sed'命令不是必需的。只有在源数据库和目标数据库位于同一实例时才需要。