亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

實(shí)現(xiàn)數(shù)據(jù)庫水平切分的兩個(gè)思路

 更新時(shí)間:2019年03月19日 17:18:51   作者:CODETC  
今天小編就為大家分享一篇關(guān)于實(shí)現(xiàn)數(shù)據(jù)庫水平切分的兩個(gè)思路,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧

引言

隨著互聯(lián)網(wǎng)應(yīng)用的廣泛普及,海量數(shù)據(jù)的存儲(chǔ)和訪問成為了系統(tǒng)設(shè)計(jì)的瓶頸問題。對(duì)于一個(gè)大型的互聯(lián)網(wǎng)應(yīng)用,每天幾十億的PV無疑對(duì)數(shù)據(jù)庫造成了相當(dāng)高的負(fù)載。對(duì)于系統(tǒng)的穩(wěn)定性和擴(kuò)展性造成了極大的問題。通過數(shù)據(jù)切分來提高網(wǎng)站性能,橫向擴(kuò)展數(shù)據(jù)層已經(jīng)成為架構(gòu)研發(fā)人員首選的方式。

  • 水平切分?jǐn)?shù)據(jù)庫:可以降低單臺(tái)機(jī)器的負(fù)載,同時(shí)最大限度的降低了宕機(jī)造成的損失;
  • 負(fù)載均衡策略:可以降低單臺(tái)機(jī)器的訪問負(fù)載,降低宕機(jī)的可能性;
  • 集群方案:解決了數(shù)據(jù)庫宕機(jī)帶來的單點(diǎn)數(shù)據(jù)庫不能訪問的問題;
  • 讀寫分離策略:最大限度了提高了應(yīng)用中讀取數(shù)據(jù)的速度和并發(fā)量;

為什么要數(shù)據(jù)切分

上面對(duì)什么是數(shù)據(jù)切分做了個(gè)概要的描述和解釋,讀者可能會(huì)疑問,為什么需要數(shù)據(jù)切分呢?像Oracle這樣成熟穩(wěn)定的數(shù)據(jù)庫,足以支撐海量數(shù)據(jù)的存儲(chǔ)與查詢了?為什么還需要數(shù)據(jù)切片呢?

的確,Oracle的DB確實(shí)很成熟很穩(wěn)定,但是高昂的使用費(fèi)用和高端的硬件支撐不是每一個(gè)公司能支付的起的。試想一下一年幾千萬的使用費(fèi)用和動(dòng)輒上千萬元的小型機(jī)作為硬件支撐,這是一般公司能支付的起的嗎?即使就是能支付的起,假如有更好的方案,有更廉價(jià)且水平擴(kuò)展性能更好的方案,我們?yōu)槭裁床贿x擇呢?

我們知道每臺(tái)機(jī)器無論配置多么好它都有自身的物理上限,所以當(dāng)我們應(yīng)用已經(jīng)能觸及或遠(yuǎn)遠(yuǎn)超出單臺(tái)機(jī)器的某個(gè)上限的時(shí)候,我們惟有尋找別的機(jī)器的幫助或者繼續(xù)升級(jí)的我們的硬件,但常見的方案還是橫向擴(kuò)展,通過添加更多的機(jī)器來共同承擔(dān)壓力。我們還得考慮當(dāng)我們的業(yè)務(wù)邏輯不斷增長(zhǎng),我們的機(jī)器能不能通過線性增長(zhǎng)就能滿足需求?Sharding可以輕松的將計(jì)算,存儲(chǔ),I/O并行分發(fā)到多臺(tái)機(jī)器上,這樣可以充分利用多臺(tái)機(jī)器各種處理能力,同時(shí)可以避免單點(diǎn)失敗,提供系統(tǒng)的可用性,進(jìn)行很好的錯(cuò)誤隔離。

綜合以上因素,數(shù)據(jù)切分是很有必要的。 我們用免費(fèi)的MySQL和廉價(jià)的Server甚至是PC做集群,達(dá)到小型機(jī)+大型商業(yè)DB的效果,減少大量的資金投入,降低運(yùn)營(yíng)成本,何樂而不為呢?

在大中型項(xiàng)目中,在數(shù)據(jù)庫設(shè)計(jì)的時(shí)候,考慮到數(shù)據(jù)庫最大承受數(shù)據(jù)量,通常會(huì)把數(shù)據(jù)庫或者數(shù)據(jù)表水平切分,以降低單個(gè)庫,單個(gè)表的壓力。這里介紹兩個(gè)項(xiàng)目中常用的數(shù)據(jù)表切分方法。當(dāng)然這些方法都是在程序中?使用一定的技巧來路由到具體的表的。首先我們要確認(rèn)根據(jù)什么來水平切分?在我們的系統(tǒng)(SNS)中,用戶的UID貫穿系統(tǒng),唯一自增長(zhǎng),根據(jù)這個(gè)字段分表,再好不過。

方法一:使用MD5哈希

做法是對(duì)UID進(jìn)行md5加密,然后取前幾位(我們這里取前兩位),然后就可以將不同的UID哈希到不同的用戶表(user_xx)中了。

function getTable( $uid ){
 $ext = substr ( md5($uid) ,0 ,2 );
 return "user_".$ext;
}

通過這個(gè)技巧,我們可以將不同的UID分散到256中用戶表中,分別是user_00,user_01 ...... user_ff。因?yàn)閁ID是數(shù)字且遞增,根據(jù)md5的算法,可以將用戶數(shù)據(jù)幾乎很均勻的分別到不同的user表中。

但是這里有個(gè)問題是,如果我們的系統(tǒng)的用戶越來越多,勢(shì)必單張表的數(shù)據(jù)量越來越大,而且根據(jù)這種算法無法擴(kuò)展表,這又會(huì)回到文章開頭出現(xiàn)的問題了。

方法二:使用移位

具體方法是:

public function getTable( $uid ) {
 return "user_" . sprintf( "d", ($uid >> 20) );
}

這里,我們將uid向右移動(dòng)20位,這樣我們就可以把大約前100萬的用戶數(shù)據(jù)放在第一個(gè)表user_0000,第二個(gè)100萬的用戶數(shù)據(jù)放在第二個(gè)表user_0001中,這樣一直下去,如果我們的用戶越來越多,直接添加用戶表就行了。由于我們保留的表后綴是四位,這里我們可以添加1萬張用戶表,即user_0000,user_0001 ...... user_9999。一萬張表,每張表100萬數(shù)據(jù),我們可以存100億條用戶記錄。當(dāng)然,如果你的用戶數(shù)據(jù)比這還多,也不要緊,你只要改變保留表后綴來增加可以擴(kuò)展的表就行了,如如果有1000億條數(shù)據(jù),每個(gè)表存100萬,那么你需要10萬張表,我們只要保留表后綴為6位即可。

上面的算法還可以寫的靈活點(diǎn):

/**
 * 根據(jù)UID分表算法
 * @param int $uid //用戶ID
 * @param int $bit  //表后綴保留幾位
 * @param int $seed //向右移動(dòng)位數(shù)
 */
function getTable( $uid , $bit , $seed ){
 return "user_" . sprintf( "%0{$bit}d" , ($uid >> $seed) );
}

小結(jié)

上面兩種方法,都要對(duì)我們當(dāng)前系統(tǒng)的用戶數(shù)據(jù)量做出可能最大的預(yù)估,并且對(duì)數(shù)據(jù)庫單個(gè)表的最大承受量做出預(yù)估。

比如第二種方案,如果我們預(yù)估我們系統(tǒng)的用戶是100億,單張表的最優(yōu)數(shù)據(jù)量是100萬,那么我們就需要將UID移動(dòng)20來確保每個(gè)表是100萬的數(shù)據(jù),保留用戶表(user_xxxx)四位來擴(kuò)展1萬張表。

又如第一種方案,每張表100萬,md5后取前兩位,就只能有256張表了,系統(tǒng)總數(shù)據(jù)庫就是:256*100萬;如果你系統(tǒng)的總數(shù)據(jù)量的比這還多,那你實(shí)現(xiàn)肯定要MD5取前三位或者四位甚至更多位了。

兩種方法都是將數(shù)據(jù)水平切分到不同的表中,相對(duì)第一種方法,第二種方法更具擴(kuò)展性。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • mysql默認(rèn)編碼為UTF-8 通過修改my.ini實(shí)現(xiàn)方法

    mysql默認(rèn)編碼為UTF-8 通過修改my.ini實(shí)現(xiàn)方法

    這篇文章主要介紹了mysql默認(rèn)編碼為UTF-8 通過修改my.ini實(shí)現(xiàn)方法的相關(guān)資料,為了防止出現(xiàn)亂碼,Latin1是不支持漢字的,所以要將其改為UTF-8或GBK,需要的朋友可以參考下
    2017-01-01
  • 與MSSQL對(duì)比學(xué)習(xí)MYSQL的心得(七)--查詢

    與MSSQL對(duì)比學(xué)習(xí)MYSQL的心得(七)--查詢

    在這個(gè)《與MSSQL對(duì)比學(xué)習(xí)MYSQL的心得》系列里面,我一直都把MYSQL跟SQLSERVER進(jìn)行比較,相互進(jìn)行比較是學(xué)習(xí)一樣?xùn)|西比較好的方法
    2014-08-08
  • mysql 5.7.13 安裝配置方法圖文教程(win10 64位)

    mysql 5.7.13 安裝配置方法圖文教程(win10 64位)

    這篇文章主要為大家分享了win10 64位下mysql 5.7.13 安裝配置方法圖文教程,感興趣的朋友可以參考一下
    2017-02-02
  • 詳解mysql中的靜態(tài)變量的作用

    詳解mysql中的靜態(tài)變量的作用

    這篇文章主要介紹了詳解mysql中的靜態(tài)變量的作用的相關(guān)資料,希望通過本大家能理解掌握MySQL 靜態(tài)變量的用法,需要的朋友可以參考下
    2017-09-09
  • MySQL判斷時(shí)間段是否重合的兩種方法

    MySQL判斷時(shí)間段是否重合的兩種方法

    這篇文章介紹了MySQL判斷時(shí)間段是否重合的兩種方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • mysql中四種備份模式

    mysql中四種備份模式

    本文主要介紹了mysql中四種備份模式,無論使用哪種備份方式,都需要根據(jù)業(yè)務(wù)需求和數(shù)據(jù)量大小來選擇合適的備份策略,并定期驗(yàn)證備份是否有效,感興趣的可以了解一下
    2023-11-11
  • MySQL中使用表別名與字段別名的基本教程

    MySQL中使用表別名與字段別名的基本教程

    這篇文章主要介紹了MySQL中使用表別名與字段別名的基本教程,利用SELECT語句和AS子句進(jìn)行取別名的操作,需要的朋友可以參考下
    2015-12-12
  • Mysql計(jì)算n日留存率的實(shí)現(xiàn)

    Mysql計(jì)算n日留存率的實(shí)現(xiàn)

    本文主要介紹了Mysql計(jì)算n日留存率的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • mysql排序失效問題的解決

    mysql排序失效問題的解決

    本文主要介紹了mysql排序失效問題的解決,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 淺談MySQL 統(tǒng)計(jì)行數(shù)的 count

    淺談MySQL 統(tǒng)計(jì)行數(shù)的 count

    這篇文章主要介紹了MySQL 統(tǒng)計(jì)行數(shù)的 count的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07

最新評(píng)論