tp6数据库配置需协同config/database.php与.env,关键参数包括deploy=>1启用连接复用、rw_separate=>false确保单库复用、pool_size控制连接数、break_reconnect=>true开启断线重试、charset必须为utf8mb4;pdo持久化无效,字段缓存需手动实现。

ThinkPHP 6 的数据库配置不是“填完账号密码就完事”,很多性能问题和连接异常,根源都在 config/database.php 和 .env 的配合方式上。直接改配置文件不如先搞清哪些参数真起作用、哪些只是摆设。
为什么加了 PDO::ATTR_PERSISTENT => true 还没效果
TP6 默认的 PDO 连接器会主动销毁连接:它的 Connection::__destruct() 方法里强制执行 $this->pdo = null,导致持久化标志被绕过。即使你在 params 里写了这个选项,show processlist 也看不到复用连接,QPS 上去照样报 Too many connections。
- MySQL 原生
mysql驱动(非 mysqlnd)根本不识别 DSN 中的persistent参数 - TP6 官方不维护
mysqli驱动,所以配'persistent' => true在mysql类型下无效 - 真正生效的是
'deploy' => 1—— 它启用框架级连接复用逻辑,不依赖 PDO 底层持久化
deploy => 1 是高并发下最务实的“长连接”替代方案
这个配置项常被误解为“只用于读写分离”,其实它在单库场景下也能激活连接池式复用。只要 deploy 设为 1,TP6 就会缓存同配置(相同 host、port、db name、user)的 PDO 实例,后续请求直接复用,避免反复握手。
- 必须配
'rw_separate' => false(即使不走从库),否则复用逻辑可能被跳过 - 可选配
'pool_size' => 20控制最大空闲连接数,防止 MySQL 端max_connections被耗尽 - 注意:换数据库名、改用户名或密码都会触发新连接池创建,不会复用旧池
- 该机制不自动清理空闲连接,长期运行需配合
max_idle_time或外部定时任务
字段缓存和断线重连必须手动开,TP6 不默认启用
Db::getFields() 每次都走 SHOW COLUMNS,不做任何缓存;break_reconnect 默认是 false,网络抖动时直接抛异常。这两个配置不显式打开,等于把性能和稳定性让渡给运气。
- 字段缓存要靠
Cache::remember()手动包裹,例如:Cache::remember('fields_user', 86400, function () { return Db::name('user')->getFields(); }) -
'fields_cache' => true这个配置项在 TP6 中已废弃,不要写进database.php -
'break_reconnect' => true必须显式配置,否则连接中断后不会自动重试 - 搭配
'params' => [\PDO::ATTR_TIMEOUT => 5]可防慢查询拖垮整个连接池
环境变量和字符集配置最容易踩坑
把密码写死在 database.php 里是安全红线;而用错字符集会导致中文乱码、emoji 插入失败、甚至索引失效(如 utf8 不支持四字节 UTF-8 字符)。
- 务必用
.env管理敏感信息:DATABASE_USERNAME=root,然后在配置中用env('database.username', 'root') -
charset必须设为utf8mb4,同时确保 MySQL 服务端的collation_server和表/列的COLLATE也匹配 - 多数据库场景下,
connections数组里的每个连接都要独立配env(),不能共用同一组变量名 - 如果用了 Swoole 协程,
config/swoole.php中的pool.db配置优先级高于database.php,别漏掉
最常被忽略的是连接池生命周期和 MySQL 服务端参数的协同:光调大 pool_size 没用,必须同步检查 MySQL 的 max_connections、wait_timeout 和 interactive_timeout,否则连接会在框架不知情时被服务端悄悄断开。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











