Hyperf 多数据库需显式配置独立连接池,连接名全小写无特殊字符,参数完整不继承 default,运行时须主动指定 connection 名调用;跨库事务不支持,关联查询需手动 on() 切换。

Hyperf 默认只配置一个数据库连接(default),若需接入第二数据库(比如业务库+日志库、主库+从库、MySQL+PostgreSQL),不能复用 default 配置块,必须显式定义独立连接池,并确保名称规范、参数完整、运行时精准调用。
配置第二数据库连接(config/autoload/database.php)
在 database.php 中新增一个完整连接配置,关键点:
- 连接名必须全小写、无点号、无大写字母(如
log_db✅,LogDB❌,log.db❌) - 所有连接参数(
driver、host、port、database、username、password、charset)都要单独写,不可依赖或继承default的值 - 显式声明
pool子项:'enable_pool' => true,并按目标数据库实际承载力设min_connections和max_connections - 若第二库是 PostgreSQL 或 MySQL 5.7/8.0 等有协议差异的版本,还需补全
options(如认证方式、预处理开关)
运行时切换到第二数据库
Hyperf 不支持自动上下文继承,必须主动指定连接名:
- 原生查询:先
Db::connection('log_db'),再链式调用table()、select()等,顺序不能颠倒 - Eloquent 模型:在模型类顶部加
protected $connection = 'log_db';,仅对静态查询方法(all()、find())生效;实例操作(new Xxx()->save())仍走 default - 手动获取连接实例:
Db::connection('log_db')->getPdo()可用于需要 PDO 原生对象的场景
避免常见陷阱
第二数据库容易因配置或调用不严谨导致静默失败:
-
Db::table('xxx')永远走default,哪怕前一句刚查过log_db—— 二者完全隔离 - 事务
Db::transaction()只能绑定单个连接池,跨库事务不支持,会直接报错 - 关联查询(
with())默认回退到default,每个关联模型都得单独on('log_db') - 连接名拼错、大小写不符、含空格时,
Db::connection()会抛出Connection [xxx] not found,而不是降级使用 default
多数据库场景下的扩展建议
如果第二库用途明确(如只读日志、只写审计),可进一步优化:
- 在模型中封装专用方法,例如
User::logQuery()->where(...)->get(),内部固定调用on('log_db') - 对只读库关闭严格类型检查:
'strict_type' => false,减少从库字段类型转换开销 - 若第二库是 MongoDB,必须用
hyperf/mongodb扩展单独配置,连接池按database名隔离,不能和 MySQL 共用逻辑 - Redis 多实例同理:每个新实例需在
redis.php中定义键名,并在dependencies.php中注册对应ConnectionPool


















