MySQL資料庫分表的3種方法
阿新 • • 發佈:2019-01-31
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