laravel 12 使用 TiDB(PingCAP)作为数据库

在 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 的关键步骤:

  1. 通过 MySQL 驱动配置(端口 4000,关闭严格模式)。
  2. 优化主键和事务(使用 AUTO_RANDOM 和悲观事务)。
  3. 监控慢查询(利用 TiDB 的分布式执行计划)。

如果需要处理高并发 OLTP 场景,建议:

  • 使用 TiDB 的 TIDB_SMJTIDB_INLJ 优化器 Hint。
  • 结合 TiKV 的 Region 调度策略。

遇到具体问题时,可以根据 TiDB 的日志(/var/log/tidb/tidb.log)或 EXPLAIN 结果,进一步分析!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值