分表,分庫算法


經典案例:

1:在memcache中分key存儲。主機分布式選擇主機的算法

 

一:利用crc32散列

    <?php
    //范圍:00-63
    function crc_hash(&$keyword,$n=64)
    {
    $hash = crc32($keyword) >> 16 & 0xffff;
    return sprintf("%02s",$hash % $n);
    }
    ?>

 二:當用戶數量太多(如達到千萬級別),數量量太大時,我們會根據用戶名username使用hash算法得出0-N的一個數值,將用戶信息分散存儲到N個表中,如增加用戶信息示例代碼如下:

    <?php

    function getHash(&$keyword,$n)
    {
    $hash = crc32($keyword) >> 16 & 0xffff;
    return sprintf("%02s",$hash % $n);
    }

    $table = 'userinfo_'.getHash($username,100);

    $sql = "insert into {$table} values(....)";

    $db = new models($table);//封裝的數據庫操作類
    $db->MyInsert($sql);

    ?>

 三:

hash算法一般是利用數組實現的,步驟如下:
存元素時:
1.把要存儲的元素(value)計算一個hashcode(稱為散列),這個就是key。
2.把元素存儲到以hashcode為下標的數組中。
3.若此數組下標已經有元素,則使用鏈表的方式把元素連接起來。

 

獲得元素時:
1.元素(value)計算hashcode。
2.hash表中按hashcode(key)取得元素。
3.若一個key中對應多個元素,則還需匹配是哪個元素。

 

就這么簡單,hash算法由於直接映射數組下標,所以查找算法的時間復雜度來說是O(1)的。不過若計算hashcode的算法不是很好的話,可能 造成一個桶(數組中的一個位置)內有多個元素,而有些桶內一個元素都沒有。這樣在存、取元素時都需要在桶內進行查找操作,而且造成空間的浪費。所以一個好的hashcode的算法使得任意給定的元素能夠均勻地存儲在hash表中的每個桶內,顯得尤為重要。以下給出一個非常經典的通用散列算法,經過研究人員統計分析過散列程度的。

    unsigned long hashcode(const unsigned char *name)
    {
    unsigned long h=0,g;
    while(*name)
    {
    h=(h<<4) + *name++;
    if(g=h & 0xF0000000)
    h^=g>>24;
    h &=~g;
    }
    return h;
    }

除非你對這個通用散列算法有特殊需求,導致無法滿足需要,否則應該使用這個函數。

hash算法確實應用得非常廣泛,因為其查找的速度是O(1)的。比如:如今數據的海量存取和高並發訪問的需求,造成關系數據庫逐漸退出舞台。DB中使用B+樹索引提供范圍查詢,hash(key-value)索引實現點查詢。

 

例子:

在開發中,整型的數值可以通過取模(mod)來進行分表,但是,對於帳號這種字符串類型,卻不能實現。怎么辦呢,我們可以通過CRC32這個函數來分表,函數如下:

function account_hash($account,$tail=4,$mod=1)
{
$crc32=sprintf("%u",crc32($account));//使用%u解決32位下出現負數的問題
return fmod(substr(strval($crc32),-$tail,$tail),$mod); //取模計算數值
}



 

使用這個函數,可以靈活定義分表的離散程度和分表數量

 

參考:http://www.dewen.io/q/405/%E6%B1%82mysql+%E5%88%86%E8%A1%A8%E7%9A%84%E6%84%8F%E4%B9%89

 

  1. <?php
  2. //范圍:00-63
  3. function crc_hash(&$keyword,$n=64)
  4. {
  5. $hash = crc32($keyword)>>16&0xffff;
  6. return sprintf("%02s",$hash % $n);
  7. }
  8. ?>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM