thinkphp 连接 tdsql 需配置 proxy 地址(hostname)、proxy 端口(如 5200)、逻辑库名(database)、charset=utf8mb4,禁用 deploy/rw_separate,且所有 sql 必须显式包含 shardkey 字段以确保正确路由。

ThinkPHP 本身不感知 TDSQL 的分片逻辑,shardkey 必须由 TDSQL Proxy 层识别并路由,TP 层只需按普通 MySQL 连接配置,但必须避开与分片键冲突的写法(比如手动拼表名、绕过主键插入等),否则会路由失败或数据错乱。
ThinkPHP 连接 TDSQL 实例要配哪些关键项
你不是在连某个物理节点,而是在连 TDSQL 的 Proxy 地址——它负责解析 SQL、识别 shardkey、分发到对应分片。所以连接配置里:
-
hostname填的是 Proxy 的 IP 或域名(不是后端某个 MySQL 实例) -
port是 Proxy 监听的端口(通常是5200或6200,以控制台实际分配为准) -
database填逻辑库名(TDSQL 控制台创建的分布式库,不是物理节点上的库) -
charset必须设为utf8mb4(TDSQL 默认要求,utf8会报错) -
deploy和rw_separate都保持默认值0和false:TDSQL 自己管读写分离和高可用,TP 不需要介入
TDSQL 的 shardkey 字段必须出现在 WHERE/INSERT 中
TDSQL 路由依赖 shardkey 字段值做哈希计算,如果 SQL 里没带这个字段,Proxy 就无法定位分片,可能报错 ERROR 1105 (HY000): shard key not found 或直接路由到默认分片(导致查不到数据)。
- INSERT 必须显式提供
shardkey字段值,不能依赖自增主键代替(除非主键本身就是shardkey) - SELECT/UPDATE/DELETE 必须在
WHERE条件中包含shardkey字段,且不能用函数包裹(如WHERE MD5(buyer_id) = 'xxx'会失效) - ThinkPHP 的
where()方法没问题,但避免用whereIn()传大量值——TDSQL 对多值路由支持有限,容易降级为广播查询 - 跨
shardkey的聚合(如GROUP BY不含shardkey)会被 Proxy 自动合并,性能可接受,但不能有ORDER BY + LIMIT混合使用(需加shardkey过滤才高效)
ThinkPHP 模型中不要重写表名或主键逻辑
TDSQL 要求应用层“无感”,一旦你在模型里手动干预表结构或主键生成,就可能破坏分片一致性。
- 别在模型里用
table或name指定物理表名(如tb_order_01),TDSQL 只认逻辑表名tb_order - 别覆盖
getPk()或修改autoWriteTimestamp的触发时机——TDSQL 的全局 ID 机制依赖标准主键行为 - 慎用
Db::raw()拼接非标准 SQL:像INSERT INTO tb_order SELECT ... FROM other_table这类跨表操作,若other_table不是广播表,大概率失败 - 事务内所有操作必须落在同一个
shardkey值下,否则触发两阶段提交(2PC),延迟明显上升;ThinkPHP 的transaction()没问题,但别在一个事务里混用buyer_id=1001和buyer_id=1002
最常被忽略的一点:TDSQL 的 shardkey 字段类型必须和建表时声明严格一致(比如定义为 bigint,就不能在 ThinkPHP 里传字符串 '1001'),否则哈希结果错位,数据写进错误分片,且几乎无法排查。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











