資料庫分表演算法

2021-09-06 14:52:45 字數 1994 閱讀 2271

在大中型專案中,在資料庫設計的時候,考慮到資料庫最大承受資料量,通常會把資料庫或者資料表水平切分,以降低單個庫,單個表的壓力。這裡介紹兩個專案中 常用的資料表切分方法。當然這些方法都是在程式中?使用一定的技巧來路由到具體的表的。首先我們要確認根據什麼來水平切分?在我們的系統(sns)中,用 戶的uid貫穿系統,唯一自增長,根據這個字段分表,再好不過。

function gettable( $uid )

/* * 參 數:$project 字串 專案

* $group 陣列 待進行分表的字段及值

* &$tables 陣列 目前已經分的表,以值址方式傳參

* $length 整型 擷取字串前幾位,此項與分表的資料密切相關,預設為2

* 功 能:分表引擎

*/function enginesplittable($project, $group, &$tables, $length = md5_prefix_length) else

return $table;

}

注意:md5出來的字串僅包含0~9a~f,你可以把每位看成乙個16進製制的數字。那麼 substr ( md5($uid) ,0 ,2 ) 出來的範圍就是16進製制的 00~ff,轉成10進製就是 0~16*16

md5後的各位實際上是: 10個數字 + 6個字元的組合  = 16

md5後的值要麼全是小寫字母,要麼全是大寫字母,不會出現混合的情況,所以字母就只有 a-f || a-f 這兩種之一

通過這個技巧,我們可以將不同的uid分散到256中使用者表中,分別是user_00,user_01 ...... user_ff。因為uid是數字且遞增,根據md5的演算法,可以將使用者資料幾乎很均勻的分別到不同的user表中。

但是這裡有個問題是,如果我們的系統的使用者越來越多,勢必單張表的資料量越來越大,而且根據這種演算法無法擴充套件表,這又會回到文章開頭出現的問題了。

一般情況下:設計分表之初就應該考慮到該錶能達到的最大資料量,選擇分多少張表,如果真的超過了預估,可以考慮集群。

方法二:使用移位

public function gettable( $uid )

這裡,我們將uid向右移動20位,這樣我們就可以把大約前100萬的使用者資料放在第乙個表user_0000,第二個100萬的使用者資料放在第二個表 user_0001中,這樣一直下去,如果我們的使用者越來越多,直接新增使用者表就行了。由於我們保留的表字尾是四位,這裡我們可以新增1萬張使用者表,即 user_0000,user_0001 ...... user_9999。一萬張表,每張表100萬資料,我們可以存100億條使用者記錄。當然,如果你的使用者資料比這還多,也不要緊,你只要改變保留表字尾來 增加可以擴充套件的表就行了,如如果有1000億條資料,每個表存100萬,那麼你需要10萬張表,我們只要保留表字尾為6位即可。

/**

* 根據uid分表演算法

* * @param int $uid //使用者id

* @param int $bit //表字尾保留幾位

* @param int $seed //向右移動位數

*/function gettable( $uid , $bit , $seed )d" , ($uid >> $seed) );

}

總結上面兩種方法,都要對我們當前系統的使用者資料量做出可能最大的預估,並且對資料庫單個表的最大承受量做出預估。

比如第二種方案,如果我們預估我們系統的使用者是100億,單張表的最優資料量是100萬,那麼我們就需要將uid移動20來確保每個表是100萬的資料,保留使用者表(user_***x)四位來擴充套件1萬張表。

又如第一種方案,每張表100萬,md5後取前兩位,就只能有256張表了,系統總資料庫就是:256*100萬;如果你系統的總資料量的比這還多,那你實現肯定要md5取前三位或者四位甚至更多位了。

兩種方法都是將資料水平切分到不同的表中,相對第一種方法,第二種方法更具擴充套件性。

參考:

資料庫分表

create table table1 id int 10 unsigned not null auto increment,name varchar 45 primary key id engine myisam create table table2 like table1 建立總表 creat...

資料庫分表策略

1 垂直劃分 將資料表中的某些字段提出,組成新的資料表。將群組id,id,id提出 組成gzm資料表,而將 群組,的詳細資訊單獨放在其他資料表中 在求取索引 關係時,運算元據庫效率更高。2 水平劃分 2.1物理上的水平切分 即將資料分配到不同的db伺服器上。降低單點機器的負載。2.2邏輯上的水平劃分...

資料庫分庫分表

1 基本思想之什麼是分庫分表?從字面上簡單理解,就是把原本儲存於乙個庫的資料分塊儲存到多個庫上,把原本儲存於乙個表的資料分塊儲存到多個表上。2 基本思想之為什麼要分庫分表?資料庫中的資料量不一定是可控的,在未進行分庫分表的情況下,隨著時間和業務的發展,庫中的表會越來越多,表中的資料量也會越來越大,相...