thinkphp 6 多数据库连接必须在 config/database.php 的 'connections' 数组中预定义合法连接名(如 'log_db')及完整配置(含 type、hostname 等),不可用点号或大写;db::connect('name') 绑定后所有链式操作均走该连接,模型需设 protected $connection = 'name';事务、关联查询不跨库;deploy=1 启用连接池提升复用效率。

ThinkPHP 6 多数据库连接不是靠写多个 database.php 文件,也不是靠临时传数组进 Db::connect(),而是必须在 config/database.php 的 'connections' 数组里预定义好带名字的完整配置——名字要合法、参数要齐全、每个连接必须能独立连通。
database.php 的 connections 必须显式定义连接名和完整参数
框架只认 'connections' 下的键名,Db::connect('log_db') 中的 'log_db' 必须是该数组里的一个 key。不能用点号(如 'log.db')、不能含大写字母、不能动态拼接字符串。
-
'log_db'这类连接名合法;'log.db'或'LogDB'会直接报错Connection not found - 每个连接块必须包含
'type'(如'mysql'),漏掉会导致驱动解析失败,报Class 'PDO' not found等底层错误 - 别只改
'database',hostname、port、charset、username 都得核对;常见翻车是两个连接都指向同一台 MySQL 实例,却以为分开了 -
.env只能覆盖扁平变量(如database.hostname),无法定义多维结构的connections,所以多库配置必须写死在database.php里
Db::connect() 调用后所有链式操作绑定该连接
调用 Db::connect('slave_db') 后,后续的 ->table()、->where()、->select() 全部走这个连接。但要注意:中间混入某些扩展方法可能破坏连接上下文。
- 推荐写法:
$db = Db::connect('slave_db'); $db->table('user_log')->select();—— 显式持有连接实例,避免链式中断 - 危险写法:
Db::connect('slave_db')->name('log')->cache()->select()——->cache()内部可能触发连接复用逻辑,导致查到默认库 -
->name('log')会自动拼prefix,跨库时容易错成main_db.log;改用->table('log_db.log')更可控 - 事务不跨连接:
Db::connect('a')->startTrans()和Db::connect('b')->startTrans()是两套完全隔离的事务,无法合并提交
模型类指定连接要用 protected $connection = 'xxx'
模型默认走全局 default 连接,想让某个模型固定连特定库,必须在类里声明 protected $connection 属性,而不是靠运行时切换。
- 在
UserLog模型中写protected $connection = 'log_db';,它所有find()、save()都走log_db -
with()关联查询不会跨库:即使User模型连mysql,关联的Profile模型仍按自己定义的$connection走,TP 不做跨库 JOIN - 如果真要合并数据,得手动查两次:
Db::connect('mysql')->table('user')->select()+Db::connect('log_db')->table('user_log')->where('uid', $uids)->select(),再 PHP 合并 - 不要重写
getConnection()方法——虽然可行,但属性赋值方式更稳定、优先级更高、且被官方文档明确支持
读写分离和连接池不是自动的,deploy=1 是复用关键
TP6 没有自动读写路由,所谓“从库”只是个普通连接名;真正影响连接复用效率的是 deploy 配置,不是 PDO::ATTR_PERSISTENT。
-
'deploy' => 0(默认):每次请求新建连接,高并发易触发Too many connections -
'deploy' => 1:启用连接池机制,相同配置的请求会复用已有 PDO 实例;哪怕你没配从库,也建议打开 -
'pool_size' => 20(可选):限制空闲连接数,配合 MySQL 的max_connections调优,避免服务端耗尽 - 别在配置里写
'persistent' => true—— TP6 的__destruct会强制断开,该字段基本无效
最容易被忽略的是连接名唯一性和 prefix 设置:跨库时 prefix 必须设为空字符串,否则 ->name('user') 会拼出带前缀的表名,而目标库根本没有那个前缀的表。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











