1. 程式人生 > >MySQL資料庫分表的3種方法

MySQL資料庫分表的3種方法

 
function get_hash_table($table,$userid) {  
$str = crc32($userid);   
if($str<0){  
$hash = "0".substr(abs($str), 0, 1);  
}else{   
$hash = substr($str, 0, 2);  
}   
  
return $table."_".$hash;   
}   
  
echo get_hash_table('message','user18991');    //結果為message_10  
echo get_hash_table('message','user34523');   //結果為message_13  
?>  

<?php function get_hash_table($table,$userid){  $str =crc32($userid);  if($str<0){  $hash= "0".substr(abs($str), 0,1);  }else{  $hash= substr($str, 0,2);  }  return $table."_".$hash;}  echoget_hash_table('message','user18991');    //結果為message_10echo get_hash_table('message','user34523');   //結果為message_13 ?>

說明一下,上面的這個方法,告訴我們user18991這個使用者的訊息都記錄在message_10這張表裡,user34523這個使用者的訊息都記錄在message_13這張表裡,讀取的時候,只要從各自的表中讀取就行了。

優點:避免一張表出現幾百萬條資料,縮短了一條sql的執行時間

缺點:當一種規則確定時,打破這條規則會很麻煩,上面的例子中我用的hash演算法是crc32,如果我現在不想用這個演算法了,改用md5後,會使同一個使用者的訊息被儲存到不同的表中,這樣資料亂套了。擴充套件性很差。

3,利用merge儲存引擎來實現分表

我覺得這種方法比較適合,那些沒有事先考慮,而已經出現了得,資料查詢慢的情況。這個時候如果要把已有的大資料量表分開比較痛苦,最痛苦的事就是改程式碼,因為程式裡面的sql語句已經寫好了,現在一張表要分成幾十張表,甚至上百張表,這樣sql語句是不是要重寫呢?舉個例子,我很喜歡舉子

mysql>show engines;的時候你會發現mrg_myisam其實就是merge。

檢視複製列印?
mysql> CREATE TABLE IF NOT EXISTS `user1`(   
->   `id` int(11)NOT NULL AUTO_INCREMENT,   
->   `name`varchar(50) DEFAULT NULL,  
->   `sex` int(1)NOT NULL DEFAULT '0',   
->   PRIMARY KEY(`id`)   
-> )ENGINE=MyISAM  DEFAULTCHARSET=utf8 AUTO_INCREMENT=1 ;  
Query OK, 0 rows affected (0.05 sec)  
  
mysql> CREATE TABLE IF NOT EXISTS `user2`(   
->   `id` int(11)NOT NULL AUTO_INCREMENT,   
->   `name`varchar(50) DEFAULT NULL,  
->   `sex` int(1)NOT NULL DEFAULT '0',   
->   PRIMARY KEY(`id`)   
-> )ENGINE=MyISAM  DEFAULTCHARSET=utf8 AUTO_INCREMENT=1 ;  
Query OK, 0 rows affected (0.01 sec)  
  
mysql> INSERT INTO `user1` (`name`, `sex`)VALUES('張映', 0);   
Query OK, 1 row affected (0.00 sec)  
  
mysql> INSERT INTO `user2` (`name`, `sex`)VALUES('tank', 1);   
Query OK, 1 row affected (0.00 sec)  
  
mysql> CREATE TABLE IF NOT EXISTS `alluser`(   
->   `id` int(11)NOT NULL AUTO_INCREMENT,   
->   `name`varchar(50) DEFAULT NULL,  
->   `sex` int(1)NOT NULL DEFAULT '0',   
->  INDEX(id)  
-> ) TYPE=MERGE UNION=(user1,user2)INSERT_METHOD=LAST AUTO_INCREMENT=1 ;  
Query OK, 0 rows affected, 1 warning (0.00 sec)  
  
mysql> select id,name,sex fromalluser;   
+----+--------+-----+   
| id | name   | sex|   
+----+--------+-----+   
|  1 | 張映 |  0 |   
|  1 | tank  |   1|   
+----+--------+-----+   
2 rows in set (0.00 sec)   
  
mysql> INSERT INTO `alluser` (`name`, `sex`)VALUES('tank2', 0);   
Query OK, 1 row affected (0.00 sec)  
  
mysql> select id,name,sex fromuser2   
-> ;   
+----+-------+-----+   
| id | name  | sex|   
+----+-------+-----+   
|  1 |tank  |  1 |   
|  2 | tank2 |  0 |   
+----+-------+-----+   
2 rows in set (0.00 sec)  

mysql> CREATE TABLE IF NOT EXISTS `user1`(  ->  `id` int(11) NOT NULLAUTO_INCREMENT,  ->  `name` varchar(50) DEFAULTNULL,  ->  `sex` int(1) NOT NULL DEFAULT'0',  ->  PRIMARY KEY(`id`)  -> )ENGINE=MyISAM  DEFAULTCHARSET=utf8 AUTO_INCREMENT=1 ; Query OK, 0 rows affected (0.05sec)  mysql>CREATE TABLE IF NOT EXISTS `user2`(  ->  `id` int(11) NOT NULLAUTO_INCREMENT,  ->  `name` varchar(50) DEFAULTNULL,  ->  `sex` int(1) NOT NULL DEFAULT'0',  ->  PRIMARY KEY(`id`)  -> )ENGINE=MyISAM