/* This function takes the database connection, an existing database, and the new database and duplicates everything in the new database. */
function copyDatabase($c, $oldDB, $newDB) {
// creates the schema if it does not exist
$schema = "CREATE SCHEMA IF NOT EXISTS {$newDB};";
mysqli_query($c, $schema);
// selects the new schema
mysqli_select_db($c, $newDB);
// gets all tables in the old schema
$tables = "SELECT table_name
FROM information_schema.tables
WHERE table_schema = '{$oldDB}'
AND table_type = 'BASE TABLE'";
$results = mysqli_query($c, $tables);
// checks if any tables were returned and recreates them in the new schema, adds the foreign keys, and inserts the associated data
if (mysqli_num_rows($results) > 0) {
// recreates all tables first
while ($row = mysqli_fetch_array($results)) {
$table = "CREATE TABLE {$newDB}.{$row[0]} LIKE {$oldDB}.{$row[0]}";
mysqli_query($c, $table);
}
// resets the results to loop through again
mysqli_data_seek($results, 0);
// loops through each table to add foreign key and insert data
while ($row = mysqli_fetch_array($results)) {
// inserts the data into each table
$data = "INSERT IGNORE INTO {$newDB}.{$row[0]} SELECT * FROM {$oldDB}.{$row[0]}";
mysqli_query($c, $data);
// gets all foreign keys for a particular table in the old schema
$fks = "SELECT constraint_name, column_name, table_name, referenced_table_name, referenced_column_name
FROM information_schema.key_column_usage
WHERE referenced_table_name IS NOT NULL
AND table_schema = '{$oldDB}'
AND table_name = '{$row[0]}'";
$fkResults = mysqli_query($c, $fks);
// checks if any foreign keys were returned and recreates them in the new schema
// Note: ON UPDATE and ON DELETE are not pulled from the original so you would have to change this to your liking
if (mysqli_num_rows($fkResults) > 0) {
while ($fkRow = mysqli_fetch_array($fkResults)) {
$fkQuery = "ALTER TABLE {$newDB}.{$row[0]}
ADD CONSTRAINT {$fkRow[0]}
FOREIGN KEY ({$fkRow[1]}) REFERENCES {$newDB}.{$fkRow[3]}({$fkRow[1]})
ON UPDATE CASCADE
ON DELETE CASCADE;";
mysqli_query($c, $fkQuery);
}
}
}
}
// gets all views in the old schema
$views = "SHOW FULL TABLES IN {$oldDB} WHERE table_type LIKE 'VIEW'";
$results = mysqli_query($c, $views);
// checks if any views were returned and recreates them in the new schema
if (mysqli_num_rows($results) > 0) {
while ($row = mysqli_fetch_array($results)) {
$view = "SHOW CREATE VIEW {$oldDB}.{$row[0]}";
$viewResults = mysqli_query($c, $view);
$viewRow = mysqli_fetch_array($viewResults);
mysqli_query($c, preg_replace("/CREATE(.*?)VIEW/", "CREATE VIEW", str_replace($oldDB, $newDB, $viewRow[1])));
}
}
// gets all triggers in the old schema
$triggers = "SELECT trigger_name, action_timing, event_manipulation, event_object_table, created
FROM information_schema.triggers
WHERE trigger_schema = '{$oldDB}'";
$results = mysqli_query($c, $triggers);
// checks if any triggers were returned and recreates them in the new schema
if (mysqli_num_rows($results) > 0) {
while ($row = mysqli_fetch_array($results)) {
$trigger = "SHOW CREATE TRIGGER {$oldDB}.{$row[0]}";
$triggerResults = mysqli_query($c, $trigger);
$triggerRow = mysqli_fetch_array($triggerResults);
mysqli_query($c, str_replace($oldDB, $newDB, $triggerRow[2]));
}
}
// gets all procedures in the old schema
$procedures = "SHOW PROCEDURE STATUS WHERE db = '{$oldDB}'";
$results = mysqli_query($c, $procedures);
// checks if any procedures were returned and recreates them in the new schema
if (mysqli_num_rows($results) > 0) {
while ($row = mysqli_fetch_array($results)) {
$procedure = "SHOW CREATE PROCEDURE {$oldDB}.{$row[1]}";
$procedureResults = mysqli_query($c, $procedure);
$procedureRow = mysqli_fetch_array($procedureResults);
mysqli_query($c, str_replace($oldDB, $newDB, $procedureRow[2]));
}
}
// gets all functions in the old schema
$functions = "SHOW FUNCTION STATUS WHERE db = '{$oldDB}'";
$results = mysqli_query($c, $functions);
// checks if any functions were returned and recreates them in the new schema
if (mysqli_num_rows($results) > 0) {
while ($row = mysqli_fetch_array($results)) {
$function = "SHOW CREATE FUNCTION {$oldDB}.{$row[1]}";
$functionResults = mysqli_query($c, $function);
$functionRow = mysqli_fetch_array($functionResults);
mysqli_query($c, str_replace($oldDB, $newDB, $functionRow[2]));
}
}
// selects the old schema (a must for copying events)
mysqli_select_db($c, $oldDB);
// gets all events in the old schema
$query = "SHOW EVENTS
WHERE db = '{$oldDB}';";
$results = mysqli_query($c, $query);
// selects the new schema again
mysqli_select_db($c, $newDB);
// checks if any events were returned and recreates them in the new schema
if (mysqli_num_rows($results) > 0) {
while ($row = mysqli_fetch_array($results)) {
$event = "SHOW CREATE EVENT {$oldDB}.{$row[1]}";
$eventResults = mysqli_query($c, $event);
$eventRow = mysqli_fetch_array($eventResults);
mysqli_query($c, str_replace($oldDB, $newDB, $eventRow[3]));
}
}
}
11
在没有mysqldump的情况下克隆数据库表的最佳方法:
创建一个新数据库 .
使用查询创建克隆查询:
SET @NewSchema = 'your_new_db';
SET @OldSchema = 'your_exists_db';
SELECT CONCAT('CREATE TABLE ',@NewSchema,'.',table_name, ' LIKE ', TABLE_SCHEMA ,'.',table_name,';INSERT INTO ',@NewSchema,'.',table_name,' SELECT * FROM ', TABLE_SCHEMA ,'.',table_name,';')
FROM information_schema.TABLES where TABLE_SCHEMA = @OldSchema AND TABLE_TYPE != 'VIEW';
为什么这是实际问题?因为 uploading of mysqldumps is ugly slow 如果DB超过2Gb . 而且您无法通过复制数据库文件(如快照备份)来克隆InnoDB表 .
1
创建SQL命令以复制行:
select @fromdb:="crm";
select @todb:="crmen";
SET group_concat_max_len=100000000;
SELECT GROUP_CONCAT( concat("CREATE TABLE `",@todb,"`.`",table_name,"` LIKE `",@fromdb,"`.`",table_name,"`;\n",
"INSERT INTO `",@todb,"`.`",table_name,"` SELECT * FROM `",@fromdb,"`.`",table_name,"`;")
SEPARATOR '\n\n')
as sqlstatement
FROM information_schema.tables where table_schema=@fromdb and TABLE_TYPE='BASE TABLE';
9 回答
我可以看到你说你不想使用
mysqldump
,但我在寻找类似的解决方案时到达了这个页面,其他人也可能会找到它 . 考虑到这一点,这是从Windows服务器的命令行复制数据库的简单方法:使用MySQLAdmin或您首选的方法创建目标数据库 . 在此示例中,
db2
是目标数据库,其中将复制源数据库db1
.在命令行上执行以下语句:
mysqldump -h [server] -u [user] -p[password] db1 | mysql -h [server] -u [user] -p[password] db2
注意:
-p
和[password]
之间没有空格您可以通过运行来复制没有数据的表:
(见MySQL CREATE TABLE文件)
您可以编写一个脚本,从一个数据库获取
SHOW TABLES
的输出,并将架构复制到另一个数据库 . 您应该能够引用架构表名称,如:就数据而言,你也可以在MySQL中做到这一点,但它并不一定快 . 创建引用后,可以运行以下命令来复制数据:
如果你're using MyISAM, you'最好复制表文件;它'll be much faster. You should be able to do the same if you'重新使用INNODB与per table table spaces .
如果你最终做了
INSERT INTO SELECT
,请务必暂时turn off indexes与ALTER TABLE x DISABLE KEYS
!EDIT Maatkit也有一些可能有助于同步数据的脚本 . 它可能不会更快,但你可以在没有太多锁定的情况下在实时数据上运行它们的同步脚本 .
如果您使用的是Linux,则可以使用此bash脚本:(它可能需要一些额外的代码清理,但它可以工作......而且它比mysqldump | mysql快得多)
在PHP中:
注意有一个mysqldbcopy命令作为添加mysql实用程序的一部分.... https://dev.mysql.com/doc/mysql-utilities/1.5/en/utils-task-clone-db.html
我真的不知道你的意思"local access" . 但是对于该解决方案,您需要能够通过服务器ssh访问 copy the files where is database is stored .
我不能使用mysqldump,因为我的数据库很大(7Go,mysqldump失败)如果2 mysql数据库的版本太不同它可能不起作用,你可以使用mysql -V检查你的mysql版本 .
1)将数据从远程服务器复制到本地计算机(vps是远程服务器的别名,可以用root@1.2.3.4替换)
2)导入本地计算机上复制的数据
如果您有不同的版本,则可能需要运行
所有先前的解决方案都达到了一点,然而,他们只是没有复制一切 . 我创建了一个PHP函数(尽管有点冗长),它复制了包括表,外键,数据,视图,过程,函数,触发器和事件在内的所有内容 . 这是代码:
在没有mysqldump的情况下克隆数据库表的最佳方法:
创建一个新数据库 .
使用查询创建克隆查询:
但请注意,上面的脚本只是 fast clone tables - 不是视图,触发器和用户函数:您可以通过
mysqldump --no-data --triggers -uroot -ppassword
快速获取结构,然后使用仅克隆插入语句 .为什么这是实际问题?因为 uploading of mysqldumps is ugly slow 如果DB超过2Gb . 而且您无法通过复制数据库文件(如快照备份)来克隆InnoDB表 .
创建SQL命令以复制行: