ThinkPHP6通过config/database.php中connections数组配置多个数据库连接,各连接以名称标识,使用Db::connect('name')或模型$connection属性指定,事务和JOIN不跨连接。

ThinkPHP 支持配置多个数据库连接,但不是靠“写多个 database.php 文件”实现的,而是通过在配置中定义多个连接名(connection name),再在模型或 Db 类中显式指定使用哪一个。
多个数据库连接怎么配(以 TP6 为例)
在 config/database.php 中,'connections' 是个关联数组,每个键是一个连接名,值是该连接的完整配置。你不能只改 'default',必须把所有库都列在 'connections' 下:
'connections' => [
'mysql' => [
'type' => 'mysql',
'hostname' => '127.0.0.1',
'database' => 'db_main',
'username' => 'root',
'password' => '',
],
'log_db' => [
'type' => 'mysql',
'hostname' => '127.0.0.1',
'database' => 'db_log',
'username' => 'logger',
'password' => 'xxx',
],
'slave_db' => [
'type' => 'mysql',
'hostname' => '192.168.1.100',
'database' => 'db_slave',
'username' => 'ro_user',
'password' => 'yyy',
],
],
'default' => 'mysql', // 这只是默认连接名,不参与多库逻辑
注意:'default' 只影响未显式指定连接时的行为,和“多库切换”本身无关。
怎么在代码里用指定的库(Db 类 / 模型)
连接名(如 'log_db')才是实际调用入口。所有操作必须通过它激活对应连接:
立即学习“PHP免费学习笔记(深入)”;
- 用
Db::connect('log_db')获取连接实例,后续链式操作(->table()、->select())都走这个库 - 模型类可通过
protected $connection = 'log_db';绑定,之后UserModel::select()就自动连log_db - 临时切换:模型方法内可用
$this->db()->connect('slave_db')覆盖当前连接(TP6.1+)
错误写法示例:Db::name('log_table')->select() —— 这仍走 default 连接,不会自动识别表名去查哪个库。
常见踩坑点:事务、读写分离、跨库 JOIN
多个连接之间完全隔离:
- 事务不能跨连接:在
log_db开启的事务,对mysql无效;想跨库一致?只能靠应用层补偿,别指望数据库级事务 - 读写分离要手动配:TP 自带的
'readwrite_type' => 'random'只适用于同一连接下的主从,不是“多个 connections 的负载均衡” - 跨库 JOIN 不支持:MySQL 层面允许
SELECT * FROM db1.users u JOIN db2.logs l ON u.id=l.uid,但 ThinkPHP 的查询构建器会把db2.logs当成当前连接下的表,报错“Table not found”
真要跨库关联查询,得用原生 SQL + Db::connect('mysql')->execute(),且确保目标库用户有跨库权限。
配置本身很简单,难的是连接生命周期管理、事务边界意识和 SQL 能力边界——别让配置看起来支持多库,就误以为框架能帮你兜住分布式一致性问题。



















