codeigniter支持在同一项目中配置多个同构数据库实例,只需在database.php中定义多个连接组(如default、slave1、logdb),并按需加载;各组驱动与参数结构一致,通过$this->load->database('组名', true)获取独立实例,实现读写分离与功能隔离。

CodeIgniter 支持在同一项目中配置多个同构数据库实例(比如多个 MySQL 实例),无需修改核心代码,只需在数据库配置文件中定义多个连接组,并在需要时按需加载即可。
在 database.php 中定义多个同构数据库组
打开 application/config/database.php,利用多维数组语法添加多个数据库配置。每个数组键名代表一个独立的连接组,驱动类型、参数结构保持一致即为“同构”。例如:
- default:主库(读写)
- slave1:从库 A(只读)
- slave2:从库 B(只读)
- logdb:日志专用库(写入审计数据)
配置示例(均为 MySQL,仅主机、库名、用户不同):
$db['default'] = array( 'hostname' => '192.168.1.10', 'username' => 'app_rw', 'password' => 'pw123', 'database' => 'main_db', 'dbdriver' => 'mysqli', 'char_set' => 'utf8mb4', 'dbcollat' => 'utf8mb4_unicode_ci', // 其他通用参数... ); $db['slave1'] = array( 'hostname' => '192.168.1.11', 'username' => 'app_ro', 'password' => 'ro456', 'database' => 'main_db', 'dbdriver' => 'mysqli', 'char_set' => 'utf8mb4', 'dbcollat' => 'utf8mb4_unicode_ci', // 同构:参数名、值类型、驱动完全一致 ); $db['logdb'] = array( 'hostname' => '192.168.1.12', 'username' => 'logger', 'password' => 'log789', 'database' => 'audit_log', 'dbdriver' => 'mysqli', 'char_set' => 'utf8mb4', 'dbcollat' => 'utf8mb4_unicode_ci', );
按需加载指定数据库连接
CI 不会自动加载所有组,必须显式调用 $this->load->database('组名', true) 获取对应实例。返回对象可赋值给任意变量,互不干扰:
- 在 Model 构造函数中同时加载多个(适合读写分离场景)
- 在 Controller 方法内临时加载(适合跨库查询或日志写入)
- 避免使用
$this->db全局覆盖,推荐用语义化变量名如$this->main_db、$this->log_db
示例(Model 中):
class User_model extends CI_Model {
public function __construct() {
parent::__construct();
$this->main_db = $this->load->database('default', TRUE);
$this->log_db = $this->load->database('logdb', TRUE);
}
public function create_user($data) {
$this->main_db->insert('users', $data);
$user_id = $this->main_db->insert_id();
$this->log_db->insert('operation_log', [
'action' => 'create_user',
'target_id' => $user_id,
'created_at' => date('Y-m-d H:i:s')
]);
}
}
注意连接隔离与事务边界
同构数据库之间不共享连接、不支持跨库事务(MySQL 单实例内跨库事务可行,但多实例间无法保证原子性)。因此:
- 不要在同一个事务中混用
$this->main_db和$this->slave1 - 读操作可轮询
slave1/slave2实现负载分担(需自行实现简单路由逻辑) - 写操作必须固定指向
default或其他明确的写库组 - 若需强一致性,应通过应用层补偿或最终一致性方案处理
环境适配与切换技巧
可通过 $active_group 控制默认加载组,配合环境变量更灵活:
- 开发时设
$active_group = 'default'; - 生产环境可设
$active_group = 'slave1';用于只读服务降级 - 结合
ENVIRONMENT常量,在 config/database.php 中动态分配(如测试环境用本地 SQLite,生产用远程 MySQL)
例如:
if (ENVIRONMENT === 'production') {
$db['default']['hostname'] = 'prod-master.internal';
$db['slave1']['hostname'] = 'prod-slave-01.internal';
} else {
$db['default']['hostname'] = 'localhost';
$db['slave1']['hostname'] = 'localhost';
}











