PHP国产化数据库(达梦、人大金仓、OceanBase)对接与调优体系.

📅 2026/6/19 20:44:09
PHP国产化数据库(达梦、人大金仓、OceanBase)对接与调优体系.
一套可以直接用的 PHP 对接国产数据库达梦 DM8/人大金仓 KingbaseES/OceanBase 的完整方案。核心思路一句话能走标准协议就走标准 PDO语法迁移全部交给数据库自带工具PHP 这层只做统一封装绝不自研 SQL 翻译器。---一、选型结论先看这个少走弯路 ┌─────────────────────┬───────────────────────┬────────────────────────────┬───────┬──────────────────────────────┐ │ 数据库 │ 协议本质 │ PHP 最佳驱动 │ 端口 │ 自带语法转换工具 │ ├─────────────────────┼───────────────────────┼────────────────────────────┼───────┼──────────────────────────────┤ │ OceanBase │ MySQL 协议MySQL │ pdo_mysqlPHP │2881│ OMSOceanBase 迁移服务 │ │ │ 模式 │ 自带零成本 │ │ │ ├─────────────────────┼───────────────────────┼────────────────────────────┼───────┼──────────────────────────────┤ │ 人大金仓 KingbaseES │ PostgreSQL 协议 │ pdo_pgsqlPHP 自带 │54321│ KDTS/KStudio 迁移评估 │ │ V8 │ │ │ │ │ ├─────────────────────┼───────────────────────┼────────────────────────────┼───────┼──────────────────────────────┤ │ 达梦 DM8 │ 私有协议 │ 官方 pdo_dm 扩展需编译 │5236│ DTS 数据迁移工具/│ │ │ │ │ │ 兼容模式参数 │ └─────────────────────┴───────────────────────┴────────────────────────────┴───────┴──────────────────────────────┘ 大白话-OceanBase 选 MySQL 模式PHP 当成 MySQL 用改都不用改。-金仓本质是 PostgreSQLPHP 当成 PG 用pdo_pgsql 直接连。-只有达梦是真私有协议必须装官方扩展但它给了 PDO 驱动用法和别的一样。---二、安装扩展一次性 #1)OceanBaseMySQL模式——PHP 自带啥都不用装确认开启即可 php-m|grep pdo_mysql #2)人大金仓 ——用 PostgreSQL 扩展PHP 自带 php-m|grep pdo_pgsql # 没有就装#Ubuntu:apt install php-pgsql#CentOS:yum install php-pgsql#3)达梦 ——必须编译官方 pdo_dm 扩展 # 达梦安装目录里自带源码 $DM_HOME/drivers/php_pdo/cd $DM_HOME/drivers/php_pdo/pdo_dm phpize./configure--with-php-config/usr/bin/php-config--with-pdo-dm$DM_HOME makemake install # 然后在 php.ini 里加一行#extensionpdo_dm.sophp-m|grep pdo_dm ▎ 为什么达梦要编译 因为它是私有协议PHP 官方不带。但达梦把 PDO 驱动源码直接放在安装目录里了编译一次即可用法和 ▎ MySQL 的 PDO 一模一样。---三、统一连接层核心完整代码 这一层的作用上层业务代码只认一个 Db 类底层换什么国产库都不用改业务。?phpdeclare(strict_types1);/** * 国产数据库统一连接层 * 设计原则只做连接 PDO 统一封装不做 SQL 语法翻译翻译交给数据库自带工具 */final class Db{private \PDO $pdo;private string $driver;// 当前驱动类型privatestaticarray $pool[];// 简易长连接复用池private function__construct(\PDO $pdo,string $driver){$this-pdo$pdo;$this-driver$driver;}/** * 工厂方法根据配置创建连接 * $type: oceanbase | kingbase | dm */publicstaticfunctionconnect(string $type,array $cfg):self{$key$type.md5(json_encode($cfg));if(isset(self::$pool[$key])){returnself::$pool[$key];}[$dsn,$options]self::buildDsn($type,$cfg);// 所有国产库统一的 PDO 行为保证一致性$options[\PDO::ATTR_ERRMODE\PDO::ERRMODE_EXCEPTION,// 出错抛异常别静默\PDO::ATTR_DEFAULT_FETCH_MODE\PDO::FETCH_ASSOC,// 默认关联数组\PDO::ATTR_EMULATE_PREPARESfalse,// 用真预处理防注入走执行计划\PDO::ATTR_PERSISTENTtrue,// 长连接减少握手开销];$pdonew \PDO($dsn,$cfg[user],$cfg[password],$options);$selfnewself($pdo,$type);$self-afterConnect();// 连接后做各库的环境初始化self::$pool[$key]$self;return$self;}/** * 关键不同库的 DSN 拼法这是唯一需要区分的地方 */privatestaticfunctionbuildDsn(string $type,array $cfg):array{$host$cfg[host];$db$cfg[database]??;switch($type){// OceanBase MySQL 协议端口默认 2881caseoceanbase:$port$cfg[port]??2881;$dsnmysql:host{$host};port{$port};dbname{$db};charsetutf8mb4;return[$dsn,[// MySQL 专属连接时就设好严格模式避免脏数据\PDO::MYSQL_ATTR_INIT_COMMANDSET sql_modeSTRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,]];// 人大金仓 PostgreSQL 协议端口默认 54321casekingbase:$port$cfg[port]??54321;$dsnpgsql:host{$host};port{$port};dbname{$db};return[$dsn,[]];// 达梦 私有协议端口默认 5236casedm:$port$cfg[port]??5236;// 达梦 DSNdbname 实际指连接库/服务名hostport 定位实例$dsndm:host{$host};port{$port};return[$dsn,[]];default:throw new \InvalidArgumentException(不支持的数据库类型: {$type});}}/** * 连接后初始化统一会话环境时区、编码、模式 */private functionafterConnect():void{switch($this-driver){caseoceanbase:$this-pdo-exec(SET time_zone 08:00);break;casekingbase:$this-pdo-exec(SET timezone Asia/Shanghai);$this-pdo-exec(SET client_encoding UTF8);break;casedm:// 达梦设置语句结束符/大小写敏感等会话参数按需// 例如统一日期格式方便和 Oracle 习惯对齐$this-pdo-exec(SET SCHEMA .($GLOBALS[__dm_schema]??SYSDBA));break;}}/** 查询返回多行 */public functionquery(string $sql,array $params[]):array{$stmt$this-pdo-prepare($sql);$stmt-execute($params);return$stmt-fetchAll();}/** 查询返回一行 */public functionfirst(string $sql,array $params[]):?array{$stmt$this-pdo-prepare($sql);$stmt-execute($params);$row$stmt-fetch();return$rowfalse?null:$row;}/** 增删改返回影响行数 */public functionexecute(string $sql,array $params[]):int{$stmt$this-pdo-prepare($sql);$stmt-execute($params);return$stmt-rowCount();}/** 取最后插入ID注意金仓/达梦需配合序列见下方说明 */public functionlastId(?string $seqnull):string{return$this-pdo-lastInsertId($seq);}/** 事务封装传一个闭包进来自动提交/回滚 */public functiontransaction(callable $fn){$this-pdo-beginTransaction();try{$result$fn($this);$this-pdo-commit();return$result;}catch(\Throwable $e){$this-pdo-rollBack();throw $e;}}public functionraw():\PDO{return$this-pdo;}}大白话解释这段代码-buildDsn()是唯一需要区分三种库的地方区别只有“DSN字符串怎么拼”其余完全统一。-ATTR_EMULATE_PREPARESfalse 很关键用真预处理既防 SQL 注入又能让国产库走到正确的执行计划调优基础。-ATTR_PERSISTENTtrue 开长连接国产库建连握手比 MySQL 重复用连接能省一大笔开销。-业务层永远只调 query/execute/transaction底层换库不用动业务。---四、三种库的使用示例业务代码长一个样?php// ---- OceanBase ----$obDb::connect(oceanbase,[host127.0.0.1,port2881,databasetest,userroottest,password****,]);// ---- 人大金仓 ----$kbDb::connect(kingbase,[host127.0.0.1,port54321,databasetest,usersystem,password****,]);// ---- 达梦 ----$dmDb::connect(dm,[host127.0.0.1,port5236,userSYSDBA,password****,]);// 三个库业务写法完全一样参数化查询$users$ob-query(SELECT id, name FROM users WHERE age ?,[18]);$kb-transaction(function(Db $db){$db-execute(UPDATE account SET balance balance - ? WHERE id ?,[100,1]);$db-execute(UPDATE account SET balance balance ? WHERE id ?,[100,2]);});▎ 一个必须知道的差异自增主键/拿插入ID ▎-OceanBaseMySQL 模式AUTO_INCREMENTlastId()直接拿。 ▎-金仓/达梦习惯用序列触发器或 IDENTITY 列。拿 ID 时 ▎-金仓INSERT...RETURNING id;或lastId(表名_id_seq)▎-达梦SELECT 序列名.CURRVAL;或建表时用IDENTITY(1,1)▎ ▎ 这属于数据库特性差异不是语法翻译不要在 PHP 里自己写翻译——建表时统一用IDENTITY 自增列即可抹平。---五、语法转换全部用数据库自带工具重点按你的要求 核心原则旧的 MySQL/Oracle SQL 怎么迁过来不要在 PHP 里写正则替换、不要自研翻译器。每个国产库都有官方工具兼容模式。1.OceanBase ——OMS迁移服务MySQL 模式-建库时选 MySQL 租户模式DDL/DML 语法和 MySQL99%兼容PHP 代码原样跑。-存量数据/结构迁移用官方 OMSOceanBase Migration Service-图形化配置源库MySQL/Oracle→目标 OceanBase。-自动做结构转换、全量增量同步、数据校验一站式。-Oracle 业务迁移则建 Oracle 模式租户配合 OMS 的 Oracle→OB转换。2.人大金仓 KingbaseES ——兼容模式KDTS/KStudio-建库时选 数据库兼容模式Oracle/MySQL/PG/SQLServer 模式四选一金仓内核直接吃对应语法。-迁移用官方工具-KStudio/迁移评估工具先评估源库 SQL 兼容度给报告。-KDTS数据迁移工具自动迁移表结构数据内置语法转换Oracle/MySQL →金仓。-也就是说你原来的 Oracle SQL建“Oracle兼容模式”库KDTS 迁移PHP 这层几乎不用改。3.达梦 DM8 ——兼容模式参数DTS-实例级兼容参数 COMPATIBLE_MODE在 dm.ini 配置-0达梦原生、1...不同值对应 Oracle/MySQL 等兼容让达梦直接识别对应方言。-迁移用官方 DTSDM 数据迁移工具图形化-源选 Oracle/MySQL/PG →目标达梦。-自动转换表结构、类型映射、对象视图/存过/序列并迁移数据。-大批量数据再用 dmfldr达梦的快速装载工具类似 Oracle sqlldr灌数。 ▎ 一句话总结这一节 语法兼容靠“建库时选对兼容模式”存量迁移靠“O/SKDTS/DTS”这三个官方工具自动转。PHP不碰 SQL ▎ 翻译只负责连接和执行。---六、调优体系连接SQL库参数三层 第1层PHP 连接层调优已在代码里体现-长连接 ATTR_PERSISTENT国产库建连开销大复用连接收益最大。-真预处理 EMULATE_PREPARESfalse复用执行计划、防注入。-批量写入用一个事务包起来把 N 条 INSERT 放进transaction()避免每条都 commit这是国产库写入慢的最大元凶。// 批量插入正确姿势一次事务 多值 INSERT$dm-transaction(function(Db $db)use($rows){$sqlINSERT INTO t_log(uid, action) VALUES .implode(,,array_fill(0,count($rows),(?,?)));$params[];foreach($rows as $r){$params[]$r[uid];$params[]$r[action];}$db-execute($sql,$params);// 一条语句插一批最快});第2层SQL 调优用各库自带分析工具-OceanBaseEXPLAIN 看计划obclient 里用 SHOW TRACE 看执行链路对热点表加合适索引必要时用 outline 绑定计划。-金仓EXPLAIN(ANALYZE,BUFFERS)SQL;和 PG 一样ANALYZE 表名 更新统计信息让优化器选对计划。-达梦EXPLAIN SELECT...;看计划用自带 DEM/管理工具的“SQL诊断”和DBMS_STATS 收集统计信息。 第3层数据库参数调优自带性能视图驱动-OceanBase调 memory_limit、租户 cpu/mem 配额看 gv$sql_audit 找慢 SQL。-金仓调 shared_buffers、work_mem、effective_cache_size和 PG 一致看 sys_stat_statements。-达梦调 BUFFER数据缓冲区、MAX_SESSIONS、SORT_BUF_SIZE用 DEM 控制台看 AWR 类报告找瓶颈。---七、整体落地流程照着做1.定模式OceanBase 选 MySQL 模式/金仓选对应兼容模式/达梦设 COMPATIBLE_MODE。2.装驱动MySQL、PGSQL 自带达梦编译 pdo_dm。3.迁数据OMS/KDTS/DTS 官方工具自动转结构灌数校验。不写翻译代码。4.接 PHP用上面的 Db 统一类业务只认 query/execute/transaction。5.调优连接层长连接真预处理事务批量→SQL 层EXPLAIN统计信息→参数层缓冲区内存。---总结一句大白话 国产化对接的最优解不是“PHP写得多牛”而是协议层用标准PDO、迁移层用官方自带工具、PHP 层薄薄一层统一封装。三种库里只有达梦要编译扩展其余直接复用 MySQL/PG 驱动SQL 兼容靠兼容模式语法转换靠 OMS/KDTS/DTS全程零自研翻译器这就是稳、省、快的方案。 需要我把某一个库比如达梦的存储过程调用、或金仓的 RETURNING 取ID的完整示例再展开吗