Вам нужно будет выполнить SELECT * FROM [table]
для каждой таблицы в исходной базе данных, затем выполнить большую транзакцию в целевой базе данных, которая удалит все предыдущие данные таблицы, а затем вставит новые данные.В основном что-то похожее на этот фрагмент:
<?php
// $srcDB and $destDB are instances of PDO.
// $tableNames is an array of tables in the correct order.
//
// $srcDB = new PDO(...);
// $destDB = new PDO(...);
// $tableNames = array('table1', 'table2');
$srcDB->beginTransaction();
$destDB->beginTransaction();
try {
foreach ($tableNames as $tableName) {
// Fetch records from source
$srcStatement = $srcDB->query('SELECT * FROM '.$tableName);
$rows = $srcStatement->fetchAll(PDO::FETCH_NUM);
// Free resources allocated by query
$srcStatement->closeCursor();
$srcStatement = null;
if ( count($rows) === 0 )
continue; // No rows
// Prepare records to insert
$insertValues = array();
foreach ($rows as $row)
$insertValues[] = '('.implode(',', array_map(array($destDB, 'quote'), $row)).')';
// Clear destination table
if ( $destDB->exec('DELETE FROM '.$tableName) === false )
throw new Exception('DELETE failed for table '.$tableName);
// Write records
if ( $destDB->exec('INSERT INTO '.$tableName.' VALUES '.implode(',', $insertValues)) === false )
throw new Exception('INSERT failed for table '.$tableName);
}
} catch (Exception $e) {
$srcDB->rollBack();
$destDB->rollBack();
throw $e;
}
$result = $destDB->commit();
$srcDB->rollBack(); // or $srcDB->commit() - we did not change the source DB though
if ( !$result )
throw new Exception('Commit failed');
// Success
?>
Примечания:
- По крайней мере для MySQL, цитирование INT (например, идентификаторов первичного ключа) не вызывает ошибок и работает должным образом, поэтому
$destDB->quote()
в array_map()
тогда должно быть безопасно, но я не знаю точно, применимо ли это ко всем типам данных и всем системам баз данных. - Выполнение всего за одну транзакцию предотвращает несогласованные резервные копии.
- В примере предполагается, что в обеих базах данных имеется одинаковая структура базы данных, причем все столбцы отображаются в точно в одном и том же порядке .
- Ваши таблицы должны быть удалены и построены в правильном порядке.не нарушать никаких ограничений внешнего ключа , в противном случае резервное копирование может завершиться неудачей.
- Провести расширенное тестирование (в идеале на выделенной тестовой системе с копией ваших живых данных) сразличные сценарии (некоторые или все таблицы пустые, таблицы с большим количеством строк, все таблицы не пустые и т. д.), чтобы обеспечить его надежную работу и не нарушать сценарий резервного копированияn недостаточно памяти из-за низкого значения memory_limit ).Сравните базу данных назначения с источником, выгрузив их, например, с помощью
mysqldump
или подобного, чтобы убедиться, что они идентичны и резервное копирование завершено.Вы можете даже столкнуться с неприятными ошибками PDO в худшем случае, когда вам, возможно, придется обойтись - Google и SO ваши друзья: -).
РЕДАКТИРОВАТЬ:
Oneможет дополнительно использовать специальную INFORMATION_SCHEMA базу данных для запроса имен таблиц и автоматического определения зависимостей внешнего ключа.
Кроме того, вы можете отключить проверку внешнего ключа в целевой базе данных во времяпередать (и включить их впоследствии), если у вас есть собственные ссылки на внешние ключи для предотвращения сбоев из-за нарушений ограничений.