"Turn" read discuzx3.1 database layer notes

Source: Internet
Author: User

Recently began to look at discuzx3.1 code, see the implementation of the database layer, DISCUZX database layer can support database library, distributed deployment, the main level of the table, can also be very convenient to support other databases. Performance, can do read and write separation, support data cache. It can be said that it is a perfect solution for the database layer.

The database layer is divided into three tiers, business logic layer encapsulation, abstraction layer, and driving layer.

The data abstraction layer encapsulates the definition of database operations, is responsible for parsing SQL statements, connecting the underlying driver to execute SQL, and data security filtering.

The database abstraction layer is implemented by the Discuzx_database class, and all member variables and methods of the class are static and can be called directly. In this class, the Init method is used to initialize the underlying driver, set the database configuration, and establish a default database connection. Table method, set the current operation of the data table, this method is very important, the database of distributed deployment, read and write separation, are determined by the name. This is implemented specifically in the drive layer. Other methods such as Insert,delete,update,fetch_all and so on are encapsulated the basic operation of the data table, the Checkquery method is responsible for the data security check, anti-injection. The Query method is responsible for parsing SQL statements, calling the driver layer, executing SQL statements, Quote,field_quote,field,format, and so on, to format the SQL statements.

Database-driven layer selects the database, connects directly to the database, and interacts with the database. Currently DISCUZX provides two low-level drivers, MySQL and mysqli. In MySQL, for example, the entire drive layer is actually implemented by the Db_dirver_mysql and Db_driver_mysql_slave two classes plus the database configuration file, Db_driver_mysql_salve inherits from Db_driver_mysql.

The configuration file (./config/config_global.php) Configures the read/write separation of the data tables, including multiple slave servers, distributed deployment.

$_config [' DB '] [' 1 '] [' Slave '] [' 1 '] [' dbhost '] = ' localhost '$_config[' db '] [' 1 '] [' slave '] [' 1 '] [' dbuser ']= ' root '$_ Config[' db '] [' 1 '] [' slave '] [' 1 '] [' DBPW ']= ' root '$_config[' db '] [' 1 '] [' slave '] [' 1 '] [' Dbcharset '] = ' GBK ';

Can be configured to disable data tables from the database, using comma splitting between table names

* @example Common_session, common_member These two tables read and write only from theprimary server,$_config[' db '] [' common '] [' Slave_except_ Table '] = ' common_session, Common_member ';

Distributed deployment according to data tables

@example deploy Common_member to a second server, Common_session deployed on a third server,$_config[' db '] [' map '] [' common_member '] = 2$_config[' db '] [' map '] [' common_session '] = 3;

First look at the abstraction layer (DB Class) initialization. At Discuz_application Init, call the _init_db () method

Private function _init_db () {if($this-init_db) {$driverfunction_exists( ' Mysql_connect ')? ' Db_driver_mysql ': ' Db_driver_mysqli '; if (Getglobal (' Config/db/slave ')) {$driverfunction_exists(' mysql_connect ')? ' Db_driver_mysql_slave ': ' Db_driver_mysqli_slave ';} DB:: Init ($driver$this->config[' db ']);}}

Init for abstract Layer DB

 Public Static function init ($driver$config) {self::$driver$driver; self::$dbnew$driver;self::$db->set_config ($ Config);self::$db,Connect ();}

The underlying dirver is determined based on the read-write separation in the configuration file, and Db_dirver_mysql_salve is initialized if supported from the library.

The table_name table in Db_driver_mysql is the key that implements the library, determines the database server number that currently needs to be connected according to the table name, and connects to the database, into the connection pool, and is set to the current connection.

functionTABLE_NAME ($tablename) {if(!Empty($this->MAP) &&!Empty($this->map[$tablename])) {$id=$this->map[$tablename];if(!$this->link[$id]) {$this->connect ($id);}$this->curlink =$this->link[$id];} Else {$this->curlink =$this->link[1];}return $this->tablepre.$tablename;}

To mention here, $this->link can implement a database only once, and do not need to be connected again.

When the data is written, the main library is called, while the data is read from the library, see Db_driver_mysql_salve, which overrides the table_name table, determines whether the table requires read-write separation, and determine the database server group number for the table

 Public functionTABLE_NAME ($tablename) {$this->tablename =$tablename;if(!$this->slaveexcept &&$this-excepttables) {$this->slaveexcept =In_array($tablename,$this->excepttables,true);}$this->serverid =isset($this->map[$this->tablename])?$this->map[$this->tablename]: 1;return $this->tablepre.$tablename;}

Rewrite the query method to determine if the current need to read from the library is selected and connected from the library.

 Public functionQuery$sql,$silent=false,$unbuffered=false) {if(! (!$this->slaveexcept &&Strtoupper(substr($sql, 0, 6) = = = = ' SELECT ' &&$this-_slave_connect ())) {$this-_master_connect ();}$this->tablename = ' ';$this->slaveexcept =false;returnParent::query ($sql,$silent,$unbuffered);}

The use of other methods in Db_dirver_mysql. The Set_config method, which is used to load configuration information. The content method, which connects to the corresponding database according to the server number, is stored in the connection pool and is set to the current connection. Query executes the SQL statement using the current connection. Fetch_all,fetch_first,result_first defines common operations.

The use of other methods in Db_dirver_mysql_slave. Set_config executes the parent class method, setting a data table that does not require read-write separation. _choose_slave method, in the case of multiple slave servers, select one from the library according to the weights.

At this point, the abstraction layer and the bottom of the database are basically clear.

The business logic layer is actually the encapsulation of the abstraction layer. The logical layer is actually the part of all business logic that involves database operations. Can read and write data directly through the abstraction layer's Db::query or Db::insert method. Usually, however, the operation of the data table is encapsulated again. The data table business class is in the Source/class/table directory. The data table operation classes are inherited from the Discuz_table class, which is in the Source/calss/discuz directory. The data cache for the database is also implemented in this layer.

The __coustruct method, sets the table name and primary key, sets whether to cache and cache time. This class mainly encapsulates some common database operations, such as Count,insert,delete,fetch,fetch_all. Data Cache-related methods: Gets the data cache Fetch_cache for the specified key value, stores a single record cache Store_cache, clears the specified record cache Clear_cache,update_cache updates the specified single record cache, Update_batch_ Cache Bulk Update Specifies the record cache, Reset_cache resets the cache for the specified data, and Increase_cache appends the update cache to the original cache. Methods for caching operations are called by methods of the actual database operation, such as the Fetch method:

 Public functionFetch$id,$force _from_db=false){$data=Array();if(!Empty($id)) {if($force _from_db|| ($data=$this->fetch_cache ($id)) ===false) {$data= Db::fetch_first (' SELECT * from '). Db::table ($this->_table). ' WHERE '. Db::field ($this->_PK,$id));if(!Empty($data))$this->store_cache ($id,$data);}}return $data;} Public functionStore_cache ($id,$data,$cache _ttl=NULL,$pre _cache_key=NULL) {$ret=false;if($this-_allowmem) {if($pre _cache_key===NULL)$pre _cache_key=$this-_pre_cache_key;if($cache _ttl===NULL)$cache _ttl=$this-_cache_ttl;$ret= Memory (' Set ',$id,$data,$cache _ttl,$pre _cache_key);}return $ret;}

Determines whether the cache and cache are stored, and if so, returns the cache directly, without reading the database. After the data is read from the database, it is stored in the cache. When read from the cache, it is defined by an external parameter, which is cacheable by default. In this method, the cache reads and writes are realized through memory, the memory method is defined in the Function_core file, and the specific implementation of the cache needs to be explained in another article.

At this point, the discuzx3.1 database layer has been, the analysis of a bit messy.

Original address:

http://blog.csdn.net/jetxt/article/details/17242581

"Turn" read discuzx3.1 database layer notes

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.