在 Laravel 12 中使用 TiDB(PingCAP 开源的分布式数据库,兼容 MySQL 协议)作为数据库,可以通过以下步骤完成配置和优化。TiDB 高度兼容 MySQL 5.7 协议,因此 Laravel 可直接通过 MySQL 驱动连接,但需针对分布式特性进行适配。
1. 确认 TiDB 版本和兼容性
- TiDB 版本:建议使用 5.0+ 版本(完全兼容 MySQL 5.7 协议)。
- 兼容性检查:
SELECT tidb_version(); -- 查看 TiDB 版本和功能支持
2. 配置 Laravel 连接 TiDB
(1) 修改 .env
文件
DB_CONNECTION=mysql
DB_HOST=your_tidb_host # TiDB 服务地址(如:127.0.0.1 或负载均衡地址)
DB_PORT=4000 # TiDB 默认端口(非 MySQL 的 3306)
DB_DATABASE=your_database
DB_USERNAME=root # 默认用户
DB_PASSWORD=your_password
(2) 调整 config/database.php
优化 TiDB 的分布式特性支持:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '4000'), // 注意 TiDB 默认端口是 4000
'database' => env('DB_DATABASE', 'test'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => false, // 关闭严格模式(TiDB 部分语法与 MySQL 有差异)
'engine' => null, // TiDB 自动选择存储引擎
'options' => [
PDO::ATTR_TIMEOUT => 30,
PDO::ATTR_EMULATE_PREPARES => true, // 避免预处理语句兼容性问题
],
],
3. 测试数据库连接
(1) 命令行验证
php artisan tinker
>>> DB::select('SELECT version()'); -- 应返回 TiDB 版本信息
(2) 验证分布式事务
TiDB 支持乐观事务和悲观事务,测试跨节点操作:
// 悲观事务(推荐)
DB::transaction(function () {
DB::table('users')->where('id', 1)->lockForUpdate()->first();
DB::table('orders')->insert(['user_id' => 1]);
}, 5); // 重试次数
4. 适配 TiDB 分布式特性
(1) 自增 ID 处理
TiDB 的自增 ID 是全局唯一但不连续的,需在模型中显式声明:
class User extends Model
{
public $incrementing = true; // 使用 TiDB 的自增逻辑
protected $keyType = 'int'; // 避免 Eloquent 强制转换 BIGINT
}
(2) 分片表设计
TiDB 自动分片,但需通过主键或分片键优化查询:
Schema::create('orders', function (Blueprint $table) {
$table->bigIncrements('id'); // 主键作为分片依据
$table->unsignedBigInteger('user_id');
$table->index('user_id'); // 非分片键需单独索引
});
(3) 避免热点写入
TiDB 对顺序写入(如自增 ID)敏感,可使用 AUTO_RANDOM
:
-- 在迁移文件中执行原生 SQL
DB::statement('ALTER TABLE users MODIFY COLUMN id BIGINT AUTO_RANDOM(5)');
5. 性能优化建议
(1) 批处理操作
TiDB 对批量插入性能更优:
$data = [['name' => 'A'], ['name' => 'B']];
DB::table('users')->insert($data); // 单次批量提交
(2) 索引优化
使用覆盖索引减少回表:
Schema::table('users', function (Blueprint $table) {
$table->index(['name', 'email']); // 复合索引
});
(3) 监控慢查询
通过 TiDB Dashboard 或 EXPLAIN
分析:
$results = DB::select('EXPLAIN ANALYZE SELECT * FROM users WHERE id = ?', [1]);
Log::info($results);
6. 常见问题处理
(1) 错误:Write conflict
- 原因:乐观事务冲突。
- 解决:改用悲观事务或重试机制:
DB::transaction(function () { ... }, 3); // 自动重试 3 次
(2) 错误:Error 9007
(事务超时)
- 原因:长事务阻塞。
- 解决:调整超时时间:
SET GLOBAL tidb_txn_mode = 'pessimistic'; SET GLOBAL tidb_retry_limit = 10;
(3) 数据迁移
从 MySQL 迁移到 TiDB:
- 使用
mydumper
/loader
工具(PingCAP 官方推荐)。 - 检查外键和触发器(TiDB 部分不支持)。
总结
Laravel 12 连接 TiDB 的关键步骤:
- 通过 MySQL 驱动配置(端口
4000
,关闭严格模式)。 - 优化主键和事务(使用
AUTO_RANDOM
和悲观事务)。 - 监控慢查询(利用 TiDB 的分布式执行计划)。
如果需要处理高并发 OLTP 场景,建议:
- 使用 TiDB 的
TIDB_SMJ
和TIDB_INLJ
优化器 Hint。 - 结合 TiKV 的 Region 调度策略。
遇到具体问题时,可以根据 TiDB 的日志(/var/log/tidb/tidb.log
)或 EXPLAIN
结果,进一步分析!