hyperf分库需显式指定连接名实现查询分发,不支持自动路由、跨库join或分片;配置多个全小写连接,原生查询先db::connection()再链式调用,模型用on()绑定,事务限单库,分页需估算或两阶段处理。

Hyperf 大数据分库不是靠自动路由,而是靠显式指定连接名来实现查询分发。它不支持跨库 JOIN 或自动分片,所有分库逻辑必须由业务代码控制,核心是“配置多个连接 + 运行时手动切换”。
配置多个分库连接
在 config/autoload/database.php 中定义多个独立连接,每个连接对应一个物理数据库实例:
- 连接名必须全小写、不含点号或大写字母(如 shard_0、shard_1、shard_2),否则
Db::connection('shard.0')会报错 - 每个连接需完整声明
driver、host、port、database、username、password,不可复用 default 配置块 - 建议对读库关闭严格类型:
'strict_type' => false,避免从库字段类型差异引发异常
按分片键路由查询
根据业务规则(如用户 ID 取模、租户 ID 哈希)动态选择连接名,再执行查询:
- 原生查询:先调用
Db::connection($connName),再链式调用table()、where()等方法 - Eloquent 模型:不推荐全局设
$connection,应使用on($connName)动态绑定,例如User::on('shard_1')->where('id', 123)->first() - 批量操作时注意连接一致性:同一事务内只能用一个连接,跨分库事务不支持
分页与大数据量处理
分库场景下,paginate() 无法跨库统计总数,需改用估算或两阶段查询:
- 避免
count()全量扫描,可用EXPLAIN估算或缓存总记录数 - 查列表时,先按分片分别取
forPage($page, $size),再在 PHP 层合并排序(适用于页码靠前的场景) - 超大数据导出用游标分批:禁用 PDO 缓冲(
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY = false),用fetch()循环逐行处理
关联查询与注意事项
Hyperf 不支持跨库关联,所有关联表必须落在同一分库中:
- 若订单和订单项分属不同库,不能直接
join,需先查主表,再按 ID 批量查从表(N+1 改为 2 次查询) -
with()关联默认走 default 连接,每个关联模型都需单独指定on('shard_x') - 禁止在事务中混用多个连接名,否则会触发
Connection not found或 MySQL 只读错误











