简体   繁体   中英

Routing traffic to a specific MySQL connection depending on the query type and table

For what I thought would be a common problem, after a medium amount of searching has returned nothing. I have several mysql servers with different tables on them and each is either a master or a read slave. I would like to route all SELECT and other non-table-modifying queries through a read slave and all others INSERT,UPDATE,ALTER,etc. to a master as well as make sure that the right master slave combo actually has the tables I am asking about.

TLDR : based on the tables and the query type (read or write) I want to use a different mysql connection.

In order to do this in a clean way I am making a wrapper function which will examine the query and decide which connection to use. In this function will be the gory details about which tables are on which servers and which are read slaves or masters. All that I will pass in is a string containing the sql statement. I know how I can implement this using regular expressions but I would much prefer to use a built in function if one exists to account for any variability in the SQL syntax or the possibility of statement types I don't know about.

TLDR : is there any way better than regex to get the table name(s) and the query type from a string of an sql query? What is an exhaustive list of the read type sql operations? Does anyone have a good regex already to find the parts of the sql statement for all variations of SQL queries?

I would imagine that many people have faced a similar problem in setting up their systems and at least some of them solved it in a similar way. Help on any of these directions would be greatly appreciated. Thanks for your time.

The way an ORM like Doctrine or Propel would address a situation like this would be to associate each table with a connection and then use a query object to build the resulting SQL.

For example, to build a SELECT query in Doctrine, you might do something like this:

$users = UserTable::getInstance()
  ->createQuery()                      // SELECT is the default operation.
  ->andWhere('is_active = ?', $active)
  ->fetch();

If you use a class to build the query for you in a piecewise method this way, it is fairly trivial to determine the nature of the operation and the primary table for the query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM