以上的配置实现了一主多从的结构,从服务器用以执行读查询,主服务器执行写入查询,读写分离的功能由后台代码自动完成.调用者无须关心.例如:
// 使用以上配置创建数据库连接对象 $db = Yii::createObject($config); // 通过从服务器执行查询操作 $rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll(); // 通过主服务器执行更新操作 $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();
注意:通过yii\db\Command::execute() 执行的查询被认为是写操作,所有使用yii\db\Command来执行的其他查询方法被认为是读操作.你可以通过$db->slave得到当前正在使用能够的从服务器.
Connection组件支持从服务器的负载均衡和故障转移,当第一次执行读查询时,会随即选择一个从服务器进行连接,如果连接失败则又选择另一个,如果所有从服务器都不可用,则会连接主服务器。你可以配置yii\db\Connection::serverStatusCache来记住那些不能连接的从服务器,使Yii 在一段时间[[yii\db\Connection::serverRetryInterval].内不会重复尝试连接那些根本不可用的从服务器.
注意:在上述配置中,每个从服务器连接超时时间被指定为10s. 如果在10s内不能连接,则被认为该服务器已经挂掉.你也可以自定义超时参数.
你也可以配置多主多从的结构,例如:
[ 'class' => 'yii\db\Connection', // 配置主服务器 'masterConfig' => [ 'username' => 'master', 'password' => '', 'attributes' => [ // use a smaller connection timeout PDO::ATTR_TIMEOUT => 10, ], ], // 配置主服务器组 'masters' => [ ['dsn' => 'dsn for master server 1'], ['dsn' => 'dsn for master server 2'], ], // 配置从服务器 'slaveConfig' => [ 'username' => 'slave', 'password' => '', 'attributes' => [ // use a smaller connection timeout PDO::ATTR_TIMEOUT => 10, ], ], // 配置从服务器组 'slaves' => [ ['dsn' => 'dsn for slave server 1'], ['dsn' => 'dsn for slave server 2'], ['dsn' => 'dsn for slave server 3'], ['dsn' => 'dsn for slave server 4'], ], ]
上述配置制定了2个主服务器和4个从服务器.Connection组件也支持主服务器的负载均衡和故障转移,与从服务器不同的是,如果所有主服务器都不可用,则会抛出异常.
注意:当你使用yii\db\Connection::masters来配置一个或多个主服务器时,Connection中关于数据库连接的其他属性(例如:dsn,username, password)都会被忽略.
事务默认使用主服务器的连接,并且在事务执行中的所有操作都会使用主服务器的连接,例如:
// 在主服务器连接上开始事务 $transaction = $db->beginTransaction(); try { // 所有的查询都在主服务器上执行 $rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll(); $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute(); $transaction->commit(); } catch(\Exception $e) { $transaction->rollBack(); throw $e; }
如果你想在从服务器上执行事务操作则必须要明确地指定,比如:
$transaction = $db->slave->beginTransaction();
有时你想强制使用主服务器来执行读查询,你可以调用seMaster()方法.
$rows = $db->useMaster(function ($db) { return $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll(); });
你也可以设置$db->enableSlaves 为false来使所有查询都在主服务器上执行.
操作数据库模式
获得模式信息
你可以通过 yii\db\Schema实例来获取Schema信息:
$schema = $connection->getSchema();
该实例包括一系列方法来检索数据库多方面的信息:
$tables = $schema->getTableNames();
更多信息请参考yii\db\Schema
修改模式
除了基础的 SQL 查询,yii\db\Command还包括一系列方法来修改数据库模式:
创建/重命名/删除/清空表
增加/重命名/删除/修改字段
增加/删除主键
增加/删除外键
创建/删除索引
使用示例:
// 创建表 $connection->createCommand()->createTable('post', [ 'id' => 'pk', 'title' => 'string', 'text' => 'text', ]);
完整参考请查看yii\db\Command.
SQL查询示例:
// find the customers whose primary key value is 10 $customers = Customer::findAll(10); $customer = Customer::findOne(10); // the above code is equivalent to: $customers = Customer::find()->where(['id' => 10])->all(); // find the customers whose primary key value is 10, 11 or 12. $customers = Customer::findAll([10, 11, 12]); $customers = Customer::find()->where(['IN','id',[10,11,12]])->all(); // the above code is equivalent to: $customers = Customer::find()->where(['id' => [10, 11, 12]])->all(); // find customers whose age is 30 and whose status is 1 $customers = Customer::findAll(['age' => 30, 'status' => 1]); // the above code is equivalent to: $customers = Customer::find()->where(['age' => 30, 'status' => 1])->all(); // use params binding $customers = Customer::find()->where('age=:age AND status=:status')->addParams([':age'=>30,':status'=>1])->all(); // use index $customers = Customer::find()->indexBy('id')->where(['age' => 30, 'status' => 1])->all(); // get customers count $count = Customer::find()->where(['age' => 30, 'status' => 1])->count(); // add addition condition $customers = Customer::find()->where(['age' => 30, 'status' => 1])->andWhere('score > 100')->orderBy('id DESC')->offset(5)->limit(10)->all(); // find by sql $customers = Customer::findBySql('SELECT * FROM customer WHERE age=30 AND status=1 AND score>100 ORDER BY id DESC LIMIT 5,10')->all();
修改: