在CodeIgniter PHP中跨不同服务器关联数据表的问题
解决CodeIgniter跨服务器表关联问题
当前代码使用UAT服务器的数据库连接对象执行整个查询,导致JOIN操作被发送到UAT服务器,试图关联UAT上的admins表,而非Preprod本地的admins表。以下是三种可行的解决方法:
方法一:本地连接+远程表引用(需跨库权限)
如果Preprod数据库的账号有权限访问UAT数据库,且两台服务器网络互通,可以直接使用本地数据库连接,通过「UAT数据库名.表名」的形式远程引用UAT的users表,这样整个查询会在Preprod本地执行,自然关联本地的admins表。
修改后的模型代码:
public function getAllData() { // 使用本地数据库连接 $this->db->select('u.code'); // 替换UAT_DATABASE_NAME为实际的UAT数据库名称 $this->db->from('UAT_DATABASE_NAME.users as u'); // 关联本地的admins表 $this->db->join('admins as a', 'u.code = a.code', 'LEFT'); $this->db->where('u.code !=', ''); $query = $this->db->get(); return $query->result(); }
注意:需要确保UAT数据库开放了Preprod服务器IP的访问权限,且Preprod的数据库账号拥有UAT数据库users表的查询权限。
方法二:PHP层面手动关联数据(无需跨库权限)
如果无法配置跨库访问权限,可以分两步查询数据,再在PHP代码中手动关联:
- 从UAT服务器查询所有符合条件的users数据
- 提取users的code列表,批量查询本地admins表
- 在PHP中通过code字段关联两组数据
修改后的模型代码:
public function getAllData() { // 1. 从UAT获取users数据 $this->UAT_SERVER123->select('code'); $this->UAT_SERVER123->from('users'); $this->UAT_SERVER123->where('code !=', ''); $usersQuery = $this->UAT_SERVER123->get(); $users = $usersQuery->result_array(); if (empty($users)) { return []; } // 提取所有user的code,用于批量查询 $userCodes = array_column($users, 'code'); // 2. 从本地获取匹配的admins数据 $this->db->select('code'); $this->db->from('admins'); $this->db->where_in('code', $userCodes); $adminsQuery = $this->db->get(); $admins = $adminsQuery->result_array(); // 将admins转为以code为键的数组,提升关联效率 $adminMap = array_column($admins, null, 'code'); // 3. 按LEFT JOIN逻辑关联数据(保留所有users) $result = []; foreach ($users as $user) { $result[] = [ 'code' => $user['code'], // 如需添加admin字段,可使用 $adminMap[$user['code']]['字段名'] ?? null ]; } return $result; }
方法三:使用数据库跨库映射表(以MySQL Federated为例)
如果使用MySQL数据库,可以在Preprod服务器上创建一个Federated映射表,将其关联到UAT的users表。这样映射表在本地,查询时就像操作本地表一样,直接关联本地admins表即可。
步骤1:创建Federated映射表(在Preprod数据库执行SQL)
CREATE TABLE uat_users ( -- 字段需与UAT服务器users表完全一致 code VARCHAR(255) NOT NULL ) ENGINE=FEDERATED CONNECTION='mysql://UAT_DB_USER:UAT_DB_PASSWORD@UAT_SERVER_IP/UAT_DB_NAME/users';
步骤2:修改模型代码
public function getAllData() { $this->db->select('u.code'); $this->db->from('uat_users as u'); $this->db->join('admins as a', 'u.code = a.code', 'LEFT'); $this->db->where('u.code !=', ''); $query = $this->db->get(); return $query->result(); }
注意:MySQL默认未开启Federated引擎,需在my.cnf/my.ini中添加federated参数并重启服务;同时要确保UAT数据库允许Preprod的IP访问,连接信息中的账号密码拥有UAT users表的查询权限。
内容的提问来源于stack exchange,提问作者Niranjan Kumar Chowdam
相关产品推荐
相关产品推荐

