我知道如何使用create new_table like old_table
复制表,但这也不会复制外键约束。我也可以对show create table old_table
的结果进行字符串操作(使用正则表达式替换表名和外键约束名),但这似乎容易出错。有没有更好的方法来复制表的结构,包括外键?
答案 0 :(得分:6)
根据以下信息,您可以在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;
答案 1 :(得分:3)
Wrikken的回答激发了我的灵感。让我来扩展它。
嗯,事情更复杂。见:http://dev.mysql.com/doc/refman/5.1/en/create-table.html。它说,TEMPORARY
表和其他东西也会出现问题。 Wrikken提到的解决方案是一种很好的方法,但是,您需要至少再查找一次才能获得有关UPDATE
和DELETE
规则的信息:
SELECT *
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE TABLE_NAME LIKE '<table_name>'
AND CONSTRAINT_SCHEMA = '<db_name>';
因此,获得一个简化任务的工具可能是一个好主意。我个人使用Adminer(https://sourceforge.net/projects/adminer/)。它带有一个导出整个数据库的选项(包括所有表,触发器,外键,......)。导出后(使用SQL语法),您可以轻松更改数据库名称并将其导回。我在项目的bug部分写了这篇文章(见票证380)。
也许您已经拥有自己喜欢的数据库管理员而不想要另一个。您可以按照以下步骤操作:
mysqldump
- &gt;转储数据库你得到file.sql
file.sql
Adminer
和mysqldump
都可以选择仅选择特定的表,因此您不必导出整个数据库。如果您只需要结构而不是数据,请为-d
使用mysqldump
选项,或在Adminer
中点击它。
答案 2 :(得分:2)
如果一个小的脚本脚本没问题,你可以在几行中利用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 http://stackoverflow.com/questions/12623651/
$create = preg_replace("/FK_/", "FK_TEMP_", $create);
// Create the new table
<run the $create statement>
不是很优雅,但它到目前为止工作。我在测试环境中这样做,所以我把它放在我的setUp()
方法中。
答案 3 :(得分:0)
如果您有phpMyAdmin,则只能导出表的结构,然后在.sql文件中将旧表名更改为new并将其导回。
这是相当快捷的方式
答案 4 :(得分:0)
我创建了一个bash脚本,用于将表复制到另一个数据库,并通过在键和约束上添加“ _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'命令。仅在源数据库和目标数据库位于同一实例中时才需要。
答案 5 :(得分:-2)
如果您只想清理表格,可以将所有相关数据复制到副本表格中。比截断并复制。结果是,你保留了你的FK。
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;