php分库实现
PHP 分库实现方法
分库(Database Sharding)是一种将数据分散到多个数据库中的技术,常用于解决单库性能瓶颈或数据量过大的问题。以下是几种常见的 PHP 分库实现方法:
基于业务逻辑的分库
根据业务需求将数据分散到不同的数据库。例如,用户数据按用户ID的哈希值分配到不同的库。
function getDbConnection($userId) {
$shardId = $userId % 4; // 假设分4个库
$config = [
'host' => "db_host_$shardId",
'username' => "user_$shardId",
'password' => "pass_$shardId",
'database' => "db_$shardId"
];
return new PDO(
"mysql:host={$config['host']};dbname={$config['database']}",
$config['username'],
$config['password']
);
}
使用中间件或代理
通过中间件(如 MySQL Router、ProxySQL)或框架(如 Laravel、ThinkPHP)的分库功能实现透明分库。
Laravel 配置示例:
// config/database.php
'connections' => [
'shard1' => [
'driver' => 'mysql',
'host' => 'shard1_host',
'database' => 'shard1_db',
'username' => 'shard1_user',
'password' => 'shard1_pass',
],
'shard2' => [
'driver' => 'mysql',
'host' => 'shard2_host',
'database' => 'shard2_db',
'username' => 'shard2_user',
'password' => 'shard2_pass',
],
];
分布式数据库方案
直接使用支持分片的分布式数据库系统,如 TiDB、MongoDB 的分片集群,或 MySQL 的 NDB Cluster。
TiDB 示例:
// 直接连接 TiDB 集群,分片对应用透明
$pdo = new PDO("mysql:host=tidb_proxy_host;dbname=my_db", "user", "pass");
分库路由表
维护一个路由表记录数据与库的映射关系,查询时先查路由表再连接对应库。
function getShardByOrderId($orderId) {
$pdo = new PDO("mysql:host=router_host;dbname=router_db", "user", "pass");
$stmt = $pdo->prepare("SELECT shard_name FROM shard_routes WHERE ? BETWEEN start_id AND end_id");
$stmt->execute([$orderId]);
return $stmt->fetchColumn();
}
注意事项
- 事务处理:跨库事务需要使用分布式事务解决方案(如 XA 事务)
- 全局ID生成:使用雪花算法(Snowflake)或 UUID 避免主键冲突
- 数据均衡:定期监控各分片数据量和负载,必要时进行重新分片
- 跨库查询:尽量避免,或通过冗余数据、数据聚合层解决
分库策略选择
哈希分片
通过对分片键(如用户ID)取模分配: $$shard_id = user_id \mod total_shards$$
范围分片
按数据范围划分,如按时间范围或ID范围分配到不同库。
目录分片
维护一个查找表记录每条数据所在分片位置,灵活性高但需要额外维护。
每种方法各有优劣,需根据具体业务场景选择最适合的方案。







