分享一個 MySQL 分庫分表類(php),mysql分庫

來源:互聯網
上載者:User

分享一個 MySQL 分庫分表類(php),mysql分庫

當一個表資料記錄過大時就會出現效能瓶頸,而一般對應的解決辦法是要麼做分區表,要麼分表,分區表就不說了,分表又分為垂直分割和水平分割,具體區別請自行搜尋。一般而言,分庫分表屬於水平分割,按照一定的規則將資料插入到不同的表中去。而分庫則可以很方便的轉移資料庫的壓力,比如將一個很大庫的分別放在不同的伺服器上。

下面是我寫的一個分庫分表的實現:

<?php/** * User: guoyu * Date: 14-8-12 * Time: 下午3:16 */ namespace App\Model\Database; class Config{    public $dsn;    public $user;    public $password;    /**     * @var string 分庫分表後得到的資料庫名     */    public $dbname;    /**     * @var string 分庫分表後得到的表名     */    public $table;     /**     * @var array MySQL 配置數組     */    private static $config;     /**     * @var string 設定檔路徑     */    private static $configFile = 'mysql.php';     public function __construct($dbname, $table, $id = 0)    {        if (is_null(static::$config)) {            $config = include(static::$configFile);            static::$config = $config;        }         $config = static::$config;        if (isset($config['shared']) && isset($config['shared'][$dbname])) {            $dbconfig = $config['shared'][$dbname];            $id = is_numeric($id) ? (int)$id : crc32($id);            $database_id = ($id / $dbconfig['database_split'][0]) % $dbconfig['database_split'][1];            $table_id = ($id / $dbconfig['table_split'][0]) % $dbconfig['table_split'][1];             foreach ($dbconfig['host'] as $key => $conf) {                list($from, $to) = explode('-', $key);                if ($from <= $database_id && $database_id <= $to) {                    $the_config = $conf;                }            }             $this->dbname = $dbname . '_' . $database_id;            $this->table = $table . '_' . $table_id;        } else {            $this->dbname = $dbname;            $this->table = $table;            $the_config = $config['db'][$dbname];        }        $c = $the_config;        if (isset($c['unix_socket']) && $c['unix_socket']) {            $this->dsn = sprintf('mysql:dbname=%s;unix_socket=%s', $this->dbname, $c['unix_socket']);        } else {            $this->dsn = sprintf('mysql:dbname=%s;host=%s;port=%s', $this->dbname, $c['host'], $c['port']);        }        $this->user = $c['user'];        $this->password = $c['password'];    } }

Config 類就做一個事情,根據設定檔,去拿到對應的庫和表的連結配置,然後客戶可以根據 dsn 去連結對應的資料庫。對應的設定檔如下:

<?php/** * User: guoyu * Date: 14-8-6 * Time: 上午11:19 */ $default = array(    'unix_socket' => null,    'host' => 'localhost',    'port' => '3306',    'user' => 'root',    'password' => '',); $config = array(    // 不進行分庫分表的資料庫    'db' => array(        'my_site' => $default,    ),    // 分庫分表    'shared' => array(        'user' => array(            'host' => array(                /**                 * 編號為 0 到 10 的庫使用的連結配置                 */                '0-10' => $default,                /**                 * 編號為 11 到 28 的庫使用的連結配置                 */                '11-28' => $default,                /**                 * 編號為 29 到 99 的庫使用的連結配置                 */                '29-99' => $default,             ),             // 分庫分表規則            /**             * 下面的配置對應百庫百表             * 如果根據 uid 進行分表,假設 uid 為 543234678,對應的庫表為:             *  (543234678 / 1) % 100 = 78 為編號為 78 的庫             *  (543234678 / 100) % 100 = 46 為編號為 46 的表             */            'database_split' => array(1, 100),            'table_split' => array(100, 100),        ),    ),);  return $config;

給出一個使用這個分庫分表的例子:

<?php/** * User: guoyu * Date: 14-8-6 * Time: 上午10:23 */ namespace App\Model; use App\Model\Database\Config;use \PDO; abstract class Model{    /**     * @var Config     */    public $config;     /**     * @var PDO     */    public $connection;     protected $dbnamePrefix;    protected $tablePrefix;     /**     * @var string 分庫分表後對應的表     */    protected $table;     public function __construct($id)    {        $this->config = new Config($this->dbnamePrefix, $this->tablePrefix, $id);        $this->connection = new Pdo($this->config->dsn, $this->config->user, $this->config->password);        $this->table = $this->config->table;    }     public function update(array $data, array $where = array())    {     }     public function select(array $where)    {     }     public function insert(array $data)    {     }     public function query($sql)    {        return $this->connection->query($sql);    }}

下面這個例子展示了如何使用上述的 Model 類:

<?php/** * User: guoyu * Date: 14-8-12 * Time: 下午4:06 */ require 'Config.php';require 'Model.php'; use App\Model\Model; class User extends Model{    protected $dbnamePrefix = 'user';    protected $tablePrefix = 'userinfo';} $user = new User(4455345345); print_r($user);


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.