How to connect to distributed database in Thinkphp
Thinkphp is a mainstream framework in China, and I believe there must be many people using it. Today we will take a look at how to connect to a distributed database in Thinkphp.
Of course, we are not here to explain how to use the model to add, delete, modify, and query the database. We are doing an analysis of its underlying connection code, which can help you better understand thinkphp's operation of the database. To facilitate our future use.
1. Single database connection
When used, the connection configuration of a single database is very simple. We only need to configure some information in the configuration file.
'DB_TYPE' => 'mysql', 'DB_HOST' => '192.168.5.102', 'DB_NAME' => 'databasename', 'DB_USER' => 'user', 'DB_PWD' => 'password', 'DB_PORT' => '3306', 'DB_PREFIX' => 'onmpw_',
It can be used after the setting is completed. The default is a single database connection.
2. Distributed database connection
The connection to a single database is very simple. Let’s focus on analyzing the connection to the distributed database.
'DB_TYPE' => 'mysql', 'DB_HOST' => '192.168.5.191,192.168.5.88,192.168.5.103', 'DB_NAME' => 'test,test,test', 'DB_USER' => 'masteruser,slaveuser,slaveuser', 'DB_PWD' => 'masterpass,slavepass,slavepass', 'DB_PORT' => '3306', 'DB_PREFIX' => '', 'DB_DEPLOY_TYPE' => 1, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'DB_RW_SEPARATE' => true, // 数据库读写是否分离 主从式有效 'DB_MASTER_NUM' => 1, // 读写分离后 主服务器数量 'DB_SLAVE_NO' => '', // 指定从服务器序号
Follow the above configuration to connect to the distributed database.
Let’s look at the following options
'DB_HOST'
Distributed database, if there are several servers, you need to fill in several server addresses, and use separated by commas. If it is a master-slave distribution, the previous address must be the address of the master database.
For the following user names, passwords, listening ports, etc., of course, write down as many as you have. If the username and password of each database are the same, you can only write one.
The code for parsing these options is as follows
$_config['username'] = explode(',',$this->config['username']); $_config['password'] = explode(',',$this->config['password']); $_config['hostname'] = explode(',',$this->config['hostname']); $_config['hostport'] = explode(',',$this->config['hostport']); $_config['database'] = explode(',',$this->config['database']); $_config['dsn'] = explode(',',$this->config['dsn']); $_config['charset'] = explode(',',$this->config['charset']); ‘DB_DEPLOY_TYPE’=>1
1 means distributed, 0 means centralized (that is, a single server).
The implementation of this option is in the class Think\Db\Dirver
protected function initConnect($master=true) { if(!empty($this->config['deploy'])) // 采用分布式数据库 $this->_linkID = $this->multiConnect($master); else // 默认单数据库 if ( !$this->_linkID ) $this->_linkID = $this->connect(); }
$this->config['deploy'] represents the 'DB_DEPLOY_TYPE' configuration option, the above configuration They have been parsed before use, and the configuration items are in the $this->config array. As for how to parse the configuration file, we will not introduce it here. Those who are interested can refer to the Think\Db class.
$this->The multiConnect() function is used for distributed connections. If the 'DB_DEPLOY_TYPE' option is set to 1, this function will be executed. Otherwise, execute the $this->connect() function directly.
‘DB_RW_SEPARATE’=>true
true means reading and writing are separated; false means reading and writing are not separated.
It should be noted here that the separation of reading and writing is based on the master-slave database system. When this option is set to true, the master database writes and the slave database reads.
if($this->config['rw_separate']){ // 主从式采用读写分离 if($master) // 主服务器写入 $r = $m; else{ if(is_numeric($this->config['slave_no'])) {// 指定服务器读 $r = $this->config['slave_no']; }else{ // 读操作连接从服务器 $r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1)); // 每次随机连接的数据库 } } }else{ // 读写操作不区分服务器 $r = floor(mt_rand(0,count($_config['hostname'])-1)); // 每次随机连接的数据库 }
$this->config[‘rw_separate’] When it is true, reading and writing are separated. When it is false, reading and writing are not separated. Why does the separation of reading and writing have to be master-slave? Because the slave server cannot write and can only read, if data is written to the slave server, the data cannot be synchronized. This will cause data inconsistency. Therefore, if our system is master-slave, we must use read-write separation. In other words, the DB_RW_SEPARATE option must be configured as true.
'DB_MASTER_NUM'=>1
The number after this option indicates the number of primary servers after read and write separation. Therefore this option is also used in master-slave database systems.
The following code selects the main server.
$m = floor(mt_rand(0,$this->config['master_num']-1));
When reading from a master-slave database, select the core code to read from the slave server
$r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1)); // 每次随机连接的数据库
where $this->config[‘master_num’] represents the number of master servers.
'DB_SLAVE_NO'=> ''
Specify the serial number of the slave server for reading data. If not set, the number of slave servers will be calculated based on the number of master servers, and then one will be randomly selected for reading.
if(is_numeric($this->config['slave_no'])) {// 指定服务器读 $r = $this->config['slave_no']; }else{ // 读操作连接从服务器 $r = floor(mt_rand($this->config['master_num'],count($_config['hostname'])-1)); // 每次随机连接的数据库 }
The above is a simple explanation of the implementation code of the role of each option.
Let’s take a look at the connection part
if($m != $r ){ $db_master = array( 'username' => isset($_config['username'][$m])?$_config['username'][$m]:$_config['username'][0], 'password' => isset($_config['password'][$m])?$_config['password'][$m]:$_config['password'][0], 'hostname' => isset($_config['hostname'][$m])?$_config['hostname'][$m]:$_config['hostname'][0], 'hostport' => isset($_config['hostport'][$m])?$_config['hostport'][$m]:$_config['hostport'][0], 'database' => isset($_config['database'][$m])?$_config['database'][$m]:$_config['database'][0], 'dsn' => isset($_config['dsn'][$m])?$_config['dsn'][$m]:$_config['dsn'][0], 'charset' => isset($_config['charset'][$m])?$_config['charset'][$m]:$_config['charset'][0], ); } $db_config = array( 'username' => isset($_config['username'][$r])?$_config['username'][$r]:$_config['username'][0], 'password' => isset($_config['password'][$r])?$_config['password'][$r]:$_config['password'][0], 'hostname' => isset($_config['hostname'][$r])?$_config['hostname'][$r]:$_config['hostname'][0], 'hostport' => isset($_config['hostport'][$r])?$_config['hostport'][$r]:$_config['hostport'][0], 'database' => isset($_config['database'][$r])?$_config['database'][$r]:$_config['database'][0], 'dsn' => isset($_config['dsn'][$r])?$_config['dsn'][$r]:$_config['dsn'][0], 'charset' => isset($_config['charset'][$r])?$_config['charset'][$r]:$_config['charset'][0], ); return $this->connect($db_config,$r,$r == $m ? false : $db_master);
Seeing this, I think everyone should understand the role of $r and $m when introducing the code for each configuration option above. .
Now let's look at $r == $m ? false : $db_master. If the database reading and writing are not separated, and the reading and writing is a server, the value passed to the connect function is false. Or if the master-slave write is separated, the value passed to connect is also false. From the above code we see that if $r and $m are not equal, $db_master will be set. In fact, it is equivalent to a backup. If the selected $r server fails and cannot be connected, it will connect to $db_master.
The third parameter of the connect() function actually indicates whether to choose an alternate connection when the $db_config server connection fails. False means no reconnection, other values mean reconnection.
The core code is as follows
try{ if(empty($config['dsn'])) { $config['dsn'] = $this->parseDsn($config); } if(version_compare(PHP_VERSION,'5.3.6','<=')){ // 禁用模拟预处理语句 $this->options[PDO::ATTR_EMULATE_PREPARES] = false; } $this->linkID[$linkNum] = new PDO( $config['dsn'], $config['username'], $config['password'],$this->options); }catch (\PDOException $e) { if($autoConnection){ //$autoConnection不为false,而是默认的主服务器 trace($e->getMessage(),'','ERR'); return $this->connect($autoConnection,$linkNum); //出现异常,使用递归函数重新连接 }elseif($config['debug']){ E($e->getMessage()); } }
In this way, for the master-slave type, $r and $m will definitely not be the same. Therefore, if the selected slave server fails when reading data, the master server will be the backup and will eventually go to the master server to read. It can ensure the timeliness of data reading.
However, I always feel that it is not perfect yet. If there are multiple slave servers, and both the slave server and the master server selected during reading fail, then the data reading will fail. At this time, it should be more secure if other slave servers can be read again. Of course, the current functions of thinkphp are quite complete and sufficient for our use. But I still hope that thinkphp will become more and more perfect in the future.
I hope the above introduction can be helpful to everyone when using thinkphp for development.
Related recommendations:
ThinkPHP5 framework basic knowledge, development specifications and directory structure
ThinkPHP file caching class code sharing
ThinkPHP Db and model performance evaluation
The above is the detailed content of How to connect to distributed database in Thinkphp. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Apple's latest releases of iOS18, iPadOS18 and macOS Sequoia systems have added an important feature to the Photos application, designed to help users easily recover photos and videos lost or damaged due to various reasons. The new feature introduces an album called "Recovered" in the Tools section of the Photos app that will automatically appear when a user has pictures or videos on their device that are not part of their photo library. The emergence of the "Recovered" album provides a solution for photos and videos lost due to database corruption, the camera application not saving to the photo library correctly, or a third-party application managing the photo library. Users only need a few simple steps

How to use MySQLi to establish a database connection in PHP: Include MySQLi extension (require_once) Create connection function (functionconnect_to_db) Call connection function ($conn=connect_to_db()) Execute query ($result=$conn->query()) Close connection ( $conn->close())

To handle database connection errors in PHP, you can use the following steps: Use mysqli_connect_errno() to obtain the error code. Use mysqli_connect_error() to get the error message. By capturing and logging these error messages, database connection issues can be easily identified and resolved, ensuring the smooth running of your application.

Through the Go standard library database/sql package, you can connect to remote databases such as MySQL, PostgreSQL or SQLite: create a connection string containing database connection information. Use the sql.Open() function to open a database connection. Perform database operations such as SQL queries and insert operations. Use defer to close the database connection to release resources.

Using the database callback function in Golang can achieve: executing custom code after the specified database operation is completed. Add custom behavior through separate functions without writing additional code. Callback functions are available for insert, update, delete, and query operations. You must use the sql.Exec, sql.QueryRow, or sql.Query function to use the callback function.

JSON data can be saved into a MySQL database by using the gjson library or the json.Unmarshal function. The gjson library provides convenience methods to parse JSON fields, and the json.Unmarshal function requires a target type pointer to unmarshal JSON data. Both methods require preparing SQL statements and performing insert operations to persist the data into the database.

Use the DataAccessObjects (DAO) library in C++ to connect and operate the database, including establishing database connections, executing SQL queries, inserting new records and updating existing records. The specific steps are: 1. Include necessary library statements; 2. Open the database file; 3. Create a Recordset object to execute SQL queries or manipulate data; 4. Traverse the results or update records according to specific needs.

PHP database connection guide: MySQL: Install the MySQLi extension and create a connection (servername, username, password, dbname). PostgreSQL: Install the PgSQL extension and create a connection (host, dbname, user, password). Oracle: Install the OracleOCI8 extension and create a connection (servername, username, password). Practical case: Obtain MySQL data, PostgreSQL query, OracleOCI8 update record.
