Yii implements MySQL multi-database and read/write splitting instance analysis

Source: Internet
Author: User
Tags database sharding
This article mainly introduces how to implement MySQL multi-database and read/write separation in Yii, and analyzes in detail the method of read/write separation in the form of instances in Yii database, which is a very practical technique for developing large-scale projects, for more information, see

This article mainly introduces how to implement MySQL multi-database and read/write separation in Yii, and analyzes in detail the method of read/write separation in the form of instances in Yii database, which is a very practical technique for developing large-scale projects, for more information, see

This article analyzes how Yii implements MySQL multi-database and read/write splitting. Share it with you for your reference. The specific analysis is as follows:

Yii Framework is a high-performance PHP Framework based on components for developing large Web applications. Yii provides almost all the functions required for today's Web 2.0 application development and is also one of the most powerful frameworks. The following describes how Yii implements MySQL multi-database and read/write splitting.

Some time ago, I designed the architecture for the SNS product, conducted a lot of stress tests on the program framework, and finally selected YiiFramework. Why didn't I choose the company's internal PHP framework, in fact, the reason is very good. Although the company's framework is the accumulation of "predecessors", after all, it is not mature enough. Without the experience of large projects, it is like a young guy who is not deeply involved in the world. Yii, as a well-known open-source product, must have been used by many people, meaning that a group of people are maintaining it. Before that, I used Yii to develop large projects, yii's Design Model and Its easy-to-scale features are sufficient.

What makes SNS different from common social products is that it will eventually be able to withstand the challenges of high concurrency and large data volumes. These problems must be considered during architecture design, web Distributed, load balancing, distributed file storage, MySQL distributed or read/write splitting, NoSQL, and various caches are all essential application solutions, this article describes how to configure and use MySQL database sharding and Master/Slave read/write splitting in Yii.

Yii does not support read/write splitting by default. We can use Yii event-driven mode to implement read/write splitting for MySQL.

Yii provides a powerful CActiveRecord database operation class. You can override the getDbConnection method to implement database switching. Then, you can use the event beforeSave, beforeDelete, and beforeFind to switch between read and write servers, you also need two configuration files, dbconfig and modelconfig, to configure the database name corresponding to the master-slave database server and model respectively, with code
The DBConfig. php file is as follows:

The Code is as follows:

<? Php
Return array (
'Passport '=> array (
'Write' => array (
'Class' => 'cdbconnection ',
'Connectionstring' => 'mysql: host = 10.1.39.2; dbname = db1 ′,
'Default' => true,
// 'Enablesparamlogging' => true,
'Enablesprofiling' => true,
'Username' => 'root ',
'Password' => '',
'Charset' => 'utf8 ′,
'Schemacachingduration' => 3600,
),
'Read' => array (
Array (
'Class' => 'cdbconnection ',
'Connectionstring' => 'mysql: host = 10.1.39.3; dbname = db1,
'Default' => true,
// 'Enablesparamlogging' => true,
'Enablesprofiling' => true,
'Username' => 'root ',
'Password' => '',
'Charset' => 'utf8 ′,
'Schemacachingduration' => 3600,
),
Array (
'Class' => 'cdbconnection ',
'Connectionstring' => 'mysql: host = 10.1.39.4; dbname = db3 ′,
'Default' => true,
// 'Enablesparamlogging' => true,
'Enablesprofiling' => true,
'Username' => 'root ',
'Password' => '',
'Charset' => 'utf8 ′,
'Schemacachingduration' => 3600,
),
),
),
);


ModelConfig. php is as follows:

The Code is as follows:

<? Php
Return array (
// The key is the database name and the value is the Model.
'Passport '=> array ('user', 'post '),
'Microblog' => array ('... '),
);
?>


ActiveRecord. php is as follows:

The Code is as follows:

/**
* Implements multi-database and master-slave read/write separation based on CActiveRecord class Encapsulation
* All models must inherit classes.
*
*/
Class ActiveRecord extends CActiveRecord
{
// Model configuration
Public $ modelConfig = '';
// Database Configuration
Public $ dbConfig = '';
// Define a multi-database set
Static $ dataBase = array ();
// Current Database Name
Public $ dbName = '';
// Define the database type (read or write)
Public $ dbType = 'read'; // 'read' or 'write'
/**
* A dbname parameter is added based on the original one.
* @ Param string $ scenario Application scenario
* @ Param string $ dbname Database Name
*/
Public function _ construct ($ scenario = 'insert', $ dbname = '')
{
If (! Empty ($ dbname ))
$ This-> dbName = $ dbname;
Parent: :__ construct ($ scenario );
}
/**
* Override the getDbConnection method of the parent class.
* Switching between multiple databases and Master/Slave Databases
*/
Public function getDbConnection ()
{
// If the specified database object exists, return directly
If (self: $ dataBase [$ this-> dbName]! = Null)
Return self: $ dataBase [$ this-> dbName];
If ($ this-> dbName = 'db '){
Self: $ dataBase [$ this-> dbName] = Yii: app ()-> getDb ();
} Else {
$ This-> changeConn ($ this-> dbType );
}
If (self: $ dataBase [$ this-> dbName] instanceof CDbConnection ){
Self: $ dataBase [$ this-> dbName]-> setActive (true );
Return self: $ dataBase [$ this-> dbName];
} Else
Throw new CDbException (Yii: t ('yii', 'model requires a "db" CDbConnection application component .'));
}
/**
* Get the configuration file
* @ Param unknown_type $ type
* @ Param unknown_type $ key
*/
Private function getConfig ($ type = "modelConfig", $ key = "){
$ Config = Yii: app ()-> params [$ type];
If ($ key)
$ Config = $ config [$ key];
Return $ config;
}
/**
* Obtain the Database Name
*/
Private function getDbName (){
If ($ this-> dbName)
Return $ this-> dbName;
$ ModelName = get_class ($ this-> model ());
$ This-> modelConfig = $ this-> getConfig ('modelconfig ');
// Obtain the database name corresponding to the model
If ($ this-> modelConfig) foreach ($ this-> modelConfig as $ key => $ val ){
If (in_array ($ modelName, $ val )){
$ DbName = $ key;
Break;
}
}
Return $ dbName;
}
/**
* Switch database connection
* @ Param unknown_type $ dbtype
*/
Protected function changeConn ($ dbtype = 'read '){
If ($ this-> dbType ==$ dbtype & self: $ dataBase [$ this-> dbName]! = Null)
Return self: $ dataBase [$ this-> dbName];
$ This-> dbName = $ this-> getDbName ();
If (Yii: app ()-> getComponent ($ this-> dbName. '_'. $ dbtype )! = Null ){
Self: $ dataBase [$ this-> dbName] = Yii: app ()-> getComponent ($ this-> dbName. '_'. $ dbtype );
Return self: $ dataBase [$ this-> dbName];
}
$ This-> dbConfig = $ this-> getConfig ('dbconfig', $ this-> dbName );
// Configuration corresponding to the data type (the slave database is a random value)
If ($ dbtype = 'write '){
$ Config = $ this-> dbConfig [$ dbtype];
} Else {
$ Slavekey = array_rand ($ this-> dbConfig [$ dbtype]);
$ Config = $ this-> dbConfig [$ dbtype] [$ slavekey];
}
// Add database configuration to component
If ($ dbComponent = Yii: createComponent ($ config )){
Yii: app ()-> setComponent ($ this-> dbName. '_'. $ dbtype, $ dbComponent );
Self: $ dataBase [$ this-> dbName] = Yii: app ()-> getComponent ($ this-> dbName. '_'. $ dbtype );
$ This-> dbType = $ dbtype;
Return self: $ dataBase [$ this-> dbName];
} Else
Throw new CDbException (Yii: t ('yii', 'model requires a "changeConn" CDbConnection application component .'));
}
/**
* Select the primary database before saving the data
*/
Protected function beforeSave (){
Parent: beforeSave ();
$ This-> changeConn ('write ');
Return true;
}
/**
* Select the primary database before deleting the data.
*/
Protected function beforeDelete (){
Parent: beforeDelete ();
$ This-> changeConn ('write ');
Return true;
}
/**
* Select to read data from the database
*/
Protected function beforeFind (){
Parent: beforeFind ();
$ This-> changeConn ('read ');
Return true;
}
/**
* Obtain the master database object
*/
Public function dbWrite (){
Return $ this-> changeConn ('write ');
}
/**
* Get the slave library object
*/
Public function dbRead (){
Return $ this-> changeConn ('read ');
}
}

This is the class I wrote and put it in the components folder. Then, all models inherit the ActiveRecord class to implement multi-database and master-slave read/write separation, how to support native SQL and use read/write splitting at the same time has been implemented.

I hope this article will help you design PHP programs based on the Yii framework.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.