簡單說明一下,假設原始表結構:
ID | username | passwd | ... | |
10000001 | 小強 | [email protected] | xxxxxxxxxxxx | ... |
10000002 | 張三 | [email protected] | xxxxxxxxxxxx | ... |
... | ... | ... | ... | ... |
以用戶名做hash把所有用戶打散到不同的表,如取md5('小強')的首英文字母(hash方法很多,這邊簡單以md5示例)進行橫向分表後假設創建如下表名:
users_a、users_b、users_c、users_d、.....、users_other
users_a 設置主健基數 10000000
users_b 設置主健基數 20000000
users_c 設置主健基數 30000000
....
這樣以後,若我們查詢 username='小張',則hash後得到小張所在的表名爲 users_a,構建sql語句:
select * from users_a where username='小張';
若我們查詢用戶 ID=21001234,則可間接得到ID21001234所在的表名爲 users_b,構建sql語句:
select * from users_b where ID=21001234;
以上這些辦法都能在分表後大幅提升數據庫查詢性能。
但是,雖然解決了使用ID和username查找的問題,如果我想查找 email='[email protected]' 怎麼辦?
首先建立該字段與主鍵ID的映射關係表結構如下:
ID | |
[email protected] | 10000001 |
[email protected] | 10000002 |
... | ... |
其次,針對email的值進行散列/分表,拆分爲 email_a、email_b、email_c.....
簡單地理解就是:
email_a存放的是以郵件a開頭的所有email地址及其對應的用戶ID;
email_b存放的是以郵件b開頭的所有email地址及其對應的用戶ID.....
這樣以後,若我們查詢 email='[email protected]',則可得到該email所在的表名爲 email_a,構建sql語句:
select ID from email_a where email='[email protected]';
得到用戶ID,並根據ID查找到用戶數據,實則也是一種自創索引。
總知在大數據量、大併發應用中分表是很必要且很繁瑣的工作,而且很多時候衍生出分庫乃至分服務器等,在此也僅僅淺顯地表達一些思路,希望以此拋磚引玉,理解得不好的地方還請海涵。