mysql:复制包含外键的表结构

时间:2010-09-20 21:20:08

标签: mysql

我知道如何使用create new_table like old_table复制表,但这也不会复制外键约束。我也可以对show create table old_table的结果进行字符串操作(使用正则表达式替换表名和外键约束名),但这似乎容易出错。有没有更好的方法来复制表的结构,包括外键?

6 个答案:

答案 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提到的解决方案是一种很好的方法,但是,您需要至少再查找一次才能获得有关UPDATEDELETE规则的信息:

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)。

也许您已经拥有自己喜欢的数据库管理员而不想要另一个。您可以按照以下步骤操作:

  1. 使用mysqldump - &gt;转储数据库你得到file.sql
  2. 创建新数据库
  3. 在新数据库中执行file.sql
  4. Adminermysqldump都可以选择仅选择特定的表,因此您不必导出整个数据库。如果您只需要结构而不是数据,请为-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;