ThinkPHP 5.1 读写分离需设 DB_DEPLOY_TYPE => 1 和 DB_RW_SEPARATE => true,首地址为主库(写),后续为从库(读);事务、锁查询强制走主库,不解析SQL类型。

ThinkPHP 5.1 的 MySQL 读写分离配置,核心是启用分布式部署模式,并明确主从角色。它不依赖“自动识别 SQL 类型”这类高级路由逻辑(那是 TP6 的特性),而是基于配置结构和连接顺序做静态分发:第一个数据库地址为写库(主库),后续地址为读库(从库)。
database.php 基础主从配置(推荐方式)
在 config/database.php 中,使用数组逗号分隔的写法,配合 DB_DEPLOY_TYPE 和 DB_RW_SEPARATE 开关:
- 必须设置 'DB_DEPLOY_TYPE' => 1 —— 启用分布式数据库支持,这是读写分离的前提
- 必须设置 'DB_RW_SEPARATE' => true —— 开启读写自动分离
- 'DB_HOST'、'DB_USER'、'DB_PWD'、'DB_PORT' 等字段均支持用英文逗号分隔多个值,顺序一一对应
- 第一个值(如
'192.168.8.102')被当作主库(write),其余为从库(read),TP5.1 会随机选取一个从库执行读操作
示例配置片段:
'DB_TYPE' => 'mysql', 'DB_DEPLOY_TYPE' => 1, 'DB_RW_SEPARATE' => true, 'DB_HOST' => '192.168.8.102,192.168.8.103,192.168.8.104', 'DB_NAME' => 'myapp', 'DB_USER' => 'root,slave_user,slave_user', 'DB_PWD' => 'master_pass,slave_pass,slave_pass', 'DB_PORT' => '3306,3306,3306', 'DB_PREFIX' => 'tp_',
关键细节与常见误区
很多问题源于配置项缺失或理解偏差:
- 漏掉
'DB_DEPLOY_TYPE' => 1→ 整个读写分离逻辑不会触发,所有操作都走第一个 host - 误以为
Db::name('user')->select()会智能判断——实际只看配置结构,不解析 SQL;只要配置了分离且是纯 SELECT,就走从库 - 事务中所有查询(含 SELECT)强制走主库,无需额外设置,框架自动保障一致性
- 带锁查询(如
->lock(true)或原生 SQL 含FOR UPDATE)也强制走主库 - 如果只配了一个 host(哪怕写了
DB_RW_SEPARATE => true),读写仍都走这一个库,无法真正分离
进阶:多主 + 指定从库(可选)
若需多个写节点(少见),可加 'DB_MASTER_NUM' => 2,表示前两个 host 为可写主库(TP5.1 支持轮询写入);若想固定某次读操作走特定从库,可用 DB_SLAVE_NO 指定下标(从 0 开始):
-
'DB_SLAVE_NO' => 1→ 强制本次读取使用第二个从库(即192.168.8.103) - 该参数仅对当前请求生效,不影响全局路由策略
验证是否生效
最直接的方式是开启数据库日志或使用抓包工具观察连接目标 IP:
- 执行
Db::table('user')->insert([...])→ 应连接到192.168.8.102 - 执行
Db::table('user')->select()→ 应连接到192.168.8.103或192.168.8.104(随机) - 开启
'DB_DEBUG' => true并查看 SQL 日志中的 host 信息,也可辅助判断
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











