本文目录导读:

- 场景一:从库 A 同步到库 B(主从复制、ETL)
- 场景二:PHP 与第三方 API 数据同步
- 场景三:文件数据同步(如CSV、Excel导入)
- 场景四:Redis / 缓存与数据库同步
- 核心注意事项
- 推荐的工具/类库
- 总结:你应该选择哪种方式?
PHP 数据同步是一个比较大的话题,因为“同步”的目标不同(数据库、第三方API、文件、Redis缓存等),实现方式也不同。
为了给你最实用的答案,我将其分为最常见的数据同步场景并分别给出代码示例和方案。
从库 A 同步到库 B(主从复制、ETL)
这是最典型的需求,比如把线上库的数据同步到报表库。
方案 1:基于时间戳 / 自增ID 的增量同步(推荐)
适用于源表有 updated_at 或自增 id 的情况。
<?php
//源库连接(MySQL)
$sourceDb = new PDO('mysql:host=source_host;dbname=source_db', 'user', 'pass');
//目标库连接
$targetDb = new PDO('mysql:host=target_host;dbname=target_db', 'user', 'pass');
//假设同步用户表,记录最后同步的ID
$lastSyncId = getLastSyncId(); //从记录表中读取上次同步到的ID
$batchSize = 1000;
$stmt = $sourceDb->prepare("SELECT * FROM users WHERE id > ? ORDER BY id ASC LIMIT ?");
$stmt->execute([$lastSyncId, $batchSize]);
$insertStmt = $targetDb->prepare("REPLACE INTO users (id, name, email, created_at) VALUES (?, ?, ?, ?)");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$insertStmt->execute([
$row['id'],
$row['name'],
$row['email'],
$row['created_at']
]);
//更新最后同步的ID
updateLastSyncId($row['id']);
}
echo "同步完成,最后ID: " . $lastSyncId;
?>
方案 2:MySQL Binlog 实时监听(高级)
使用 canal 或 mysql-binlog-connector-java,然后用 PHP 消费,但这通常需要 PHP 作为消费者配合 Kafka/Redis 使用,纯 PHP 实现较少且性能一般。
PHP 与第三方 API 数据同步
订单创建后同步到 ERP 系统(金蝶、SAP),或用户信息同步到推送服务。
推荐:消息队列 + 异步消费
<?php
//生产端:创建订单后发送到队列
function createOrder($orderData) {
// ... 本地数据库插入操作
// 同步发送到队列
$queue = new RedisQueue(); //假设封装好的Redis队列
$queue->push('sync:erp:order', json_encode($orderData));
return true;
}
//消费端:独立脚本或Worker(swoole/Workerman)
while (true) {
$orderData = $queue->pop('sync:erp:order');
if ($orderData) {
$order = json_decode($orderData, true);
try {
$erpApi = new ErpApi();
$erpApi->syncOrder($order);
logSyncSuccess($order['id']);
} catch (Exception $e) {
// 记录失败,重试机制
$queue->retry('sync:erp:order:fail', $orderData);
}
}
}
文件数据同步(如CSV、Excel导入)
<?php
//读取CSV并同步到数据库
$file = fopen('data.csv', 'r');
$headers = fgetcsv($file); //跳过标题行
$db = new PDO('mysql:host=localhost;dbname=test', 'root', 'pass');
$stmt = $db->prepare("INSERT INTO products (sku, name, price, stock) VALUES (?, ?, ?, ?)
ON DUPLICATE KEY UPDATE name=VALUES(name), price=VALUES(price)");
while (($row = fgetcsv($file)) !== false) {
$stmt->execute([
$row[0], //sku
$row[1], //name
$row[2], //price
$row[3] //stock
]);
}
fclose($file);
echo "文件同步完成";
?>
Redis / 缓存与数据库同步
方案:Cache-Aside 模式
<?php
//读取数据:先查缓存,再查库,回写缓存
function getUser($userId) {
$cache = new Redis();
$user = $cache->get("user:$userId");
if (!$user) {
// 同步:从数据库加载
$user = $db->query("SELECT * FROM users WHERE id = $userId")->fetch();
if ($user) {
$cache->set("user:$userId", json_encode($user), 3600);
}
} else {
$user = json_decode($user, true);
}
return $user;
}
//更新数据:先更新数据库,再删除缓存
function updateUser($userId, $data) {
$db->update("users", $data, "id = $userId");
$cache->del("user:$userId"); //删除缓存,下次读取自动同步
}
?>
核心注意事项
- 事务与一致性:同步操作需要保证原子性,使用数据库事务。
- 失败重试:API同步或队列消费必须有重试机制,否则数据会丢失。
- 锁与并发:如果多个进程同时同步同一张表,会导致数据错乱,使用
SELECT ... FOR UPDATE或 Redis 分布式锁。 - 性能考量:
- 小批量(如1000条一批)
- 不要用
SELECT *除非所有字段都需要 - 使用
INSERT ... ON DUPLICATE KEY UPDATE代替先查后改
- 记录同步状态:建立一个
sync_log表,记录最后一次的同步时间、ID、状态等。
推荐的工具/类库
- 数据库同步:
phpMyAdmin的同步功能(适合页面操作)、MySQL Workbench、pt-table-sync(Percona Toolkit)。 - ETL 框架:Apache Airflow(调度)、Talend(重量级)、Kettle。
- PHP 中间件:supervisor(管理常驻进程)、Swoole(异步高性能)、Laravel Horizon(队列监控)。
你应该选择哪种方式?
- 一次性全量同步:直接用
mysqldump导入导出,或用 PHP 脚本分页读取写入。 - 定期增量同步(分钟~小时级):使用方案一(时间戳/ID)。
- 实时同步(秒级):使用Binlog + Canal + Kafka,PHP 作为消费者。
- 跨系统API同步:使用消息队列,保证不丢数据。
如果你能告诉我具体要同步什么(数据库到数据库?到API?文件?)和数据量级(几百条?几千万?),我能给出更精准的代码。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播