Reputation: 2233
I know how to copy a table using create new_table like old_table
, but that does not copy over the foreign key constraints as well. I can also do string manipulation on the result from show create table old_table
(using regular expressions to replace the table name and the foreign key constraint names), but that seems error prone. Is there a better way to copy the structure of a table, including the foreign keys?
Upvotes: 25
Views: 18136
Reputation: 11
I created a bash script to copy a table into another database, modifying the keys and constraints by adding a '_1' to them:
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
This works to new database instances as well, but the 'sed' command won't be necessary. It's only necessary when source and destination databases are in the same instance.
Upvotes: 0
Reputation: 483
If you just want to clean your table, you could copy all relevant data to your copy table. Than truncate and copy back. Result is, that you have your FK preserved.
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;
Upvotes: 0
Reputation: 1028
If you have phpMyAdmin, you can export only structure of your table, then change old table names to new in your .sql file and import it back.
It's rather quick way
Upvotes: 0
Reputation: 89
Wrikken's answer inspired me. Let me extend it.
Well, things are more complicated. See: http://dev.mysql.com/doc/refman/5.1/en/create-table.html. It says, that there are going to be problems also with TEMPORARY
tables and other things. The solution mentioned by Wrikken is a good approach, however, you will need at least one more lookup to get information about UPDATE
and DELETE
rules:
SELECT *
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE TABLE_NAME LIKE '<table_name>'
AND CONSTRAINT_SCHEMA = '<db_name>';
So, it might be a good idea to get a tool that simplifies the task. I personally use Adminer (https://sourceforge.net/projects/adminer/). It comes with an option to export whole DB (with all tables, triggers, foreign keys, ...). Once you export it (in SQL syntax) you can change DB name easily and import it back. I wrote about that at the bugs section of the project (see ticket 380).
Maybe you already have your favorite DB manager and do not want another one. You could follow these steps then:
mysqldump
-> you get file.sql
file.sql
in the new DBBoth Adminer
and mysqldump
have an option to select only specific tables so you do not have to export whole DB. Should you need only the structure, not the data, use an option -d
for mysqldump
or click it in Adminer
.
Upvotes: 3
Reputation: 70460
Possibly you could write a procedure that after the create table like
prepares ALTER TABLE ...
statements, based on information from:
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;
Upvotes: 6
Reputation: 57209
If a little side-scripting is OK, you can take advantage of SHOW CREATE TABLE
in a few lines like so (PHP but concept works in any language):
// 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>
Not very elegant, but it works so far. I'm doing this in a testing environment so I put this in my setUp()
method.
Upvotes: 4