當用戶數量達到百萬甚至千萬級別的時候,可能沒法靠單標知足現有需求。此時經常使用的處理方式就是分庫分表。這裏介紹一個簡單的分表方法。sql
對用戶進行分表,首先要解決的是將一個用戶分配到那個表,而後如何知道去哪一個表查詢該用戶的數據。解決了這個兩個問題。不管將該用戶的數據放在哪一個表都無所謂。數據庫
首先來看一個方法:ui
function getHash($uid) { return sprintf('%03x',intval(sprintf('%u', crc32($uid)))%512 ); }
該方法完成了如下步驟:spa
(1)經過循環冗餘校驗,每一個字符串都會生成一個固定的數字。code
(2)用該數字對512取模獲得一個0<=X<512的數字server
(3)再用16進制格式化,可生成一個固定的3個字符的字符串。blog
(4)該方法的做用能夠經過用戶ID生成一個固定的3個字符的字符串。根據該字符串可將該用戶分配到對應的表中。ci
不論用戶id是什麼,經過循環冗餘校驗後都能獲得一個數字。將該數字取模。而後將餘數格式化成字符串。(固然也能夠不格式化,直接用數字也能夠。)而後用該字符串作前綴或者後綴建立用戶表。字符串
例如:get
我先以固定字符串爲後綴,在user數據庫建立了user_000、user_001 … user_1ff共512張用戶表。(固然512張表的結構是如出一轍的。)
$model = new Model();
$db = 'userdb';
for($i=0; $i<512; $i++){ $num = sprintf('%03x', $i); $sql="CREATE TABLE IF NOT EXISTS `{$db}`.`user_{$num}` ( `uid` bigint(20) NOT NULL, `name` int(11) NOT NULL, `server` int(11) NOT NULL, `cid` int(11) NOT NULL, `aid` int(11) NOT NULL, `areaId` int(11) NOT NULL, `eventtime` int(11) NOT NULL, `eventdate` date NOT NULL, `eventhour` int(11) NOT NULL, PRIMARY KEY (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8"; $model->query($sql); }
而後將一個用戶ID爲test@163.com 經過以上行數進行格式化,獲得一個3個字符串:1c8 ,而後將此用戶的數據存入user.user_1c8 數據表中,之後須要用到這個用戶的數據,只要進該用戶id也就是test@163.com 經過以上方法獲得1c8 而後從數據表user.user_1c8 中查詢該用戶的數據便可。