thinkphp 6 分库必须显式配置多个独立连接并手动指定,不能依赖模型自动识别;需在 database.php 的 connections 数组中定义 'user_db' 等完整连接配置,模型通过 $connection 属性或 db::connect('name') 调用绑定,且读写分离与分库可共存但不可跨连接共享从库。

ThinkPHP 分库不是靠“模型自动识别”实现的,必须显式指定连接配置,否则所有模型默认走 default 连接 —— 这是最常踩的坑。
怎么在 database.php 里定义多个数据库连接
ThinkPHP 6 的分库本质是「多连接配置 + 显式调用」。不能只改 database 字段,必须把每个库作为独立连接写进 connections 数组里。
-
connections下每个键(如'user_db'、'admin_db')就是一个可被引用的连接名 - 每个连接必须包含完整参数:
'type'、'hostname'、'database'、'username'、'password',缺一不可 -
'default'只控制未指定连接时的 fallback,不影响模型是否分库 - 不要在
connections外层直接写'database' => 'xxx',那是旧版 TP5 的写法,TP6 会忽略
模型怎么绑定指定数据库连接
模型本身不“记住”库,它只通过 connection 属性或构造时传参来临时切换连接。两种写法效果等价:
- 在模型类中声明
protected $connection = 'user_db'; - 实例化时指定:
User::connect('user_db')->select()或Db::connect('admin_db')->name('log')->select() - 注意:
$connection是字符串,必须和connections数组里的键完全一致(区分大小写) - 如果用了模型继承
think\Model,但没设$connection,它就一定走default,哪怕表名在另一个库里存在
Db 类操作如何指定非默认库
Db 是无状态的,每次调用都要明确告诉它用哪个连接,不能“切换一次全局生效”。
- 错误写法:
Db::connect('user_db'); Db::name('users')->select();—— 第一行返回新实例但没赋值,第二行仍是默认连接 - 正确写法:
Db::connect('user_db')->name('users')->select(); - 也可以先存实例:
$db = Db::connect('admin_db');,后续都用$db->name(...) - 跨库关联查询无法自动完成,比如
User::with('admin')不会按模型各自的$connection去查,必须手写原生 SQL 或分两次查再合并
读写分离和分库能混用吗
可以,但逻辑层级不同:分库是「数据物理隔离」,读写分离是「同库内主从路由」。TP6 允许在某个连接内部再启用 rw_separate,但不能跨库做读写分离。
- 例如:你配了
'user_db'和'admin_db'两个连接,每个连接内部可单独设'rw_separate' => true,各自连自己的主从集群 - 但不能让
user_db的写走 A 服务器、读走 B 服务器,同时又让admin_db的读也走 B 服务器 —— TP6 不支持跨连接共享从库 -
slave_no是针对单个连接内的从库列表下标,不是全局序号;若某连接只配了一个从库,slave_no必须为0或留空,填1会报错
真正容易被忽略的是:模型的 $connection 属性只在首次实例化时生效,一旦模型被静态缓存(如开启 model_cache),改属性也不会重新加载 —— 所以动态切库必须用 connect() 链式调用,别依赖属性赋值。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











