架構(gòu)第2章 高性能數(shù)據(jù)庫集群

本文參考《極客時間》- 從0開始學(xué)架構(gòu)

高性能數(shù)據(jù)庫集群
第一種方式是“讀寫分離”棉胀,其本質(zhì)是將訪問壓力分散到集群中的多個節(jié)點煤裙,但是沒有分散存儲壓力;
第二種方式是“分庫分表”算灸,既可以分散訪問壓力腥沽,又可以分散存儲壓力谅将。

“讀寫分離”

讀寫分離的基本原理是將數(shù)據(jù)庫讀寫操作分散到不同的節(jié)點上漾狼。

image.png

讀寫分離的基本實現(xiàn)是:

  • 數(shù)據(jù)庫服務(wù)器搭建主從集群,一主一從饥臂、一主多從都可以逊躁。
  • 數(shù)據(jù)庫主機負責(zé)讀寫操作,從機只負責(zé)讀操作隅熙。
  • 數(shù)據(jù)庫主機通過復(fù)制將數(shù)據(jù)同步到從機稽煤,每臺數(shù)據(jù)庫服務(wù)器都存儲了所有的業(yè)務(wù)數(shù)據(jù)。
  • 業(yè)務(wù)服務(wù)器將寫操作發(fā)給數(shù)據(jù)庫主機囚戚,將讀操作發(fā)給數(shù)據(jù)庫從機酵熙。
    需要注意的是,這里用的是“主從集群”驰坊,而不是“主備集群”匾二。
    “從機”是需要提供讀數(shù)據(jù)的功能的;而“備機”一般被認為僅僅 提供備份功能,不提供訪問功能拳芙。
    所以使用“主從”還是“主備”察藐,是要看場景的,這兩個詞并不是完全等同的舟扎。
    寫分離的實現(xiàn)邏輯并不復(fù)雜分飞,但有兩個細節(jié)點將引入設(shè)計復(fù)雜度: 主從復(fù)制延遲 和 分配機制 。
復(fù)制延遲

以MySQL為例睹限,主從復(fù)制延遲可能達到1秒譬猫,如果有大量數(shù)據(jù)同步,延遲1分鐘也是有可能的羡疗。
主從復(fù)制延遲會帶來一個問題:如果業(yè)務(wù)服務(wù)器將數(shù)據(jù)寫入到數(shù)據(jù)庫主服務(wù)器后立刻 (1秒內(nèi))進行讀取染服,此時讀操作訪問的是從機,主機還沒有將數(shù)據(jù)復(fù)制過來叨恨,到從機讀取數(shù)據(jù)是讀不到最新數(shù)據(jù)的肌索,業(yè)務(wù)上就可能出現(xiàn)問題。
例如特碳,用戶剛注冊完后立刻登錄诚亚,業(yè) 務(wù)服務(wù)器會提示他“你還沒有注冊”,而用戶明明剛才已經(jīng)注冊成功了午乓。

  • 解決主從復(fù)制延遲有幾種常見的方法:
    (1)寫操作后的讀操作指定發(fā)給數(shù)據(jù)庫主服務(wù)器
    例如站宗,注冊賬號完成后,登錄時讀取賬號的讀操作也發(fā)給數(shù)據(jù)庫主服務(wù)器益愈。這種方式和業(yè)務(wù)強綁定梢灭,對業(yè)務(wù)的侵入和影響較大夷家,如果哪個新來的程序員不知道這樣寫代碼,就會導(dǎo)致一個bug敏释。
    (2)讀從機失敗后再讀一次主機 這就是通常所說的“二次讀取”库快,二次讀取和業(yè)務(wù)無綁定,只需要對底層數(shù)據(jù)庫訪問的API進行封裝即可钥顽,實現(xiàn)代價較小义屏,不足之處在于如果有很多二次讀取,將大大增加主機的讀操
    作壓力蜂大。例如闽铐,黑客暴力破解賬號,會導(dǎo)致大量的二次讀取操作奶浦,主機可能頂不住讀操作的壓力從而崩潰
    (3)關(guān)鍵業(yè)務(wù)讀寫操作全部指向主機兄墅,非關(guān)鍵業(yè)務(wù)采用讀寫分離
    例如,對于一個用戶管理系統(tǒng)來說澳叉,注冊+登錄的業(yè)務(wù)讀寫操作全部訪問主機隙咸,用戶的介紹、愛好成洗、等級等業(yè)務(wù)五督,可以采用讀寫分離,因為即使用戶改了自己的自我介紹泌枪,在查詢時 卻看到了自我介紹還是舊的概荷,業(yè)務(wù)影響與不能登錄相比就小很多秕岛,還可以忍受碌燕。

備注:當(dāng)然,用戶登錄這種情況继薛,可以通過redis緩存來處理修壕。注冊之后,用戶信息存緩存遏考。登錄先查緩存
并不是說一有性能問題就上讀寫分離慈鸠,而是應(yīng)該先優(yōu)化,例如優(yōu)化慢查詢灌具,調(diào)整不合理的業(yè)務(wù)邏輯青团,引入緩存等,只有確定系統(tǒng)沒有優(yōu)化空間后咖楣,才考慮讀寫分離或者集群督笆。

分配機制
  • 將讀寫操作區(qū)分開來,然后訪問不同的數(shù)據(jù)庫服務(wù)器诱贿,一般有兩種方式:程序代碼封裝和中間件封裝娃肿。
    (1)程序代碼封裝 程序代碼封裝指在代碼中抽象一個數(shù)據(jù)訪問層(所以有的文章也稱這種方式為“中間層封裝”)咕缎,實現(xiàn)讀寫操作分離和數(shù)據(jù)庫服務(wù)器連接的管理。
    例如料扰,基于Hibernate進行簡單封裝凭豪,就可以實現(xiàn)讀寫分離,基本架構(gòu)是:
image.png

目前開源的實現(xiàn)方案中晒杈,淘寶的TDDL(Taobao Distributed Data Layer嫂伞,外號:頭都大了)是比較有名的。它是一個通用數(shù)據(jù)訪問層桐智,所有功能封裝在jar包中提供給業(yè)務(wù)代碼調(diào) 用末早。
其基本原理是一個基于集中式配置的 jdbc datasource實現(xiàn),具有主備说庭、讀寫分離然磷、動態(tài)數(shù)據(jù)庫配置等功能,基本架構(gòu)是:

image.png

.中間件封裝
(2)中間件封裝指的是獨立一套系統(tǒng)出來刊驴,實現(xiàn)讀寫操作分離和數(shù)據(jù)庫服務(wù)器連接的管理姿搜。中間件對業(yè)務(wù)服務(wù)器提供SQL兼容的協(xié)議,業(yè)務(wù)服務(wù)器無須自己進行讀寫分離。對于業(yè)務(wù)服務(wù) 器來說审胸,訪問中間件和訪問數(shù)據(jù)庫沒有區(qū)別完丽,事實上在業(yè)務(wù)服務(wù)器看來,中間件就是一個數(shù)據(jù)庫服務(wù)器致份。其基本架構(gòu)是:

image.png

數(shù)據(jù)庫中間件的方式具備的特點是: 能夠支持多種編程語言,因為數(shù)據(jù)庫中間件對業(yè)務(wù)服務(wù)器提供的是標準SQL接口础拨。
數(shù)據(jù)庫中間件要支持完整的SQL語法和數(shù)據(jù)庫服務(wù)器的協(xié)議(例如氮块,MySQL客戶端和服務(wù)器的連接協(xié)議),實現(xiàn)比較復(fù)雜诡宗,細節(jié)特別多滔蝉,很容易出現(xiàn)bug,需要較長的時間才能穩(wěn)定塔沃。
數(shù)據(jù)庫中間件自己不執(zhí)行真正的讀寫操作蝠引,但所有的數(shù)據(jù)庫操作請求都要經(jīng)過中間件,中間件的性能要求也很高蛀柴。
數(shù)據(jù)庫主從切換對業(yè)務(wù)服務(wù)器無感知螃概,數(shù)據(jù)庫中間件可以探測數(shù)據(jù)庫服務(wù)器的主從狀態(tài)。
例如鸽疾,向某個測試表寫入一條數(shù)據(jù)吊洼,成功的就是主機,失敗的就是從機肮韧。
由于數(shù)據(jù)庫中間件的復(fù)雜度要比程序代碼封裝高出一個數(shù)量級融蹂,一般情況下建議采用程序語言封裝的方式旺订,或者使用成熟的開源數(shù)據(jù)庫中間件。如果是大公司超燃,可以投入人力去實現(xiàn)數(shù)據(jù)庫中間件区拳,因為這個系統(tǒng)一旦做好,接入的業(yè)務(wù)系統(tǒng)越多意乓,節(jié)省的程序開發(fā)投入就越多樱调,價值也越大。
目前的開源數(shù)據(jù)庫中間件方案中届良,MySQL官方先是提供了MySQL Proxy笆凌,但MySQL Proxy一直沒有正式GA,現(xiàn)在MySQL官方推薦MySQL Router士葫。MySQL Router的主要功能 有讀寫分離乞而、故障自動切換、負載均衡慢显、連接池等爪模,其基本架構(gòu)如下:

image.png

“分庫分表”

讀寫分離分散了數(shù)據(jù)庫讀寫操作的壓力,但沒有分散存儲壓力荚藻。
當(dāng)數(shù)據(jù)量達到千萬甚至上億條的時候屋灌,單臺數(shù)據(jù)庫服務(wù)器的存儲能力會成為系統(tǒng)的瓶頸,主要體現(xiàn)在這幾個方面:
1)數(shù)據(jù)量太大应狱,讀寫的性能會下降共郭,即使有索引,索引也會變得很大疾呻,性能同樣會下降除嘹。
2)數(shù)據(jù)文件會變得很大,數(shù)據(jù)庫備份和恢復(fù)需要耗費很長時間罐韩。
3)數(shù)據(jù)文件越大憾赁,極端情況下丟失數(shù)據(jù)的風(fēng)險越高(例如污朽,機房火災(zāi)導(dǎo)致數(shù)據(jù)庫主備機都發(fā)生故障)散吵。

做分庫分表前依次嘗試這些方式是否可以達到目的:

1.做硬件優(yōu)化,例如從機械硬盤改成使用固態(tài)硬盤蟆肆,當(dāng)然固態(tài)硬盤不適合服務(wù)器使用矾睦,只是舉個例子
2.先做數(shù)據(jù)庫服務(wù)器的調(diào)優(yōu)操作,例如增加索引炎功,oracle有很多的參數(shù)調(diào)整;
3.引入緩存技術(shù)枚冗,例如Redis,減少數(shù)據(jù)庫壓力
4.程序與數(shù)據(jù)庫表優(yōu)化蛇损,重構(gòu)赁温,例如根據(jù)業(yè)務(wù)邏輯對程序邏輯做優(yōu)化坛怪,減少不必要的查詢;
5.在這些操作都不能大幅度優(yōu)化性能的情況下,不能滿足將來的發(fā)展股囊,再考慮分庫分表袜匿,也要有預(yù)估性

分庫分表的實施前提:
  1. 數(shù)據(jù)庫存在性能問題,且用加索引稚疹、慢查詢優(yōu)化居灯、緩存和讀寫分離都無法徹底解決問題的時候
  2. 復(fù)雜查詢對應(yīng)的單表數(shù)據(jù)量級一般超過千萬以上,或簡單查詢的單表數(shù)據(jù)量級一般超過5000萬以上 3. 對一致性要求不是特別高内狗,只要求最終一致性怪嫌。
  3. 用hadoop等大數(shù)據(jù)技術(shù)因為業(yè)務(wù)需求、技術(shù)成本柳沙、時間成本無法解決該問題
    其他:
  4. 業(yè)務(wù)對數(shù)據(jù)的操作主要集中在某些字段上岩灭,比較適合垂直分表
  5. 業(yè)務(wù)對數(shù)據(jù)的操作在整個表層面較均勻分布,適合水平分表

常見的分散存儲的方法“分庫分表”赂鲤,其中包括“分庫”和“分表”兩大類川背。

業(yè)務(wù)分庫

業(yè)務(wù)分庫指的是按照業(yè)務(wù)模塊將數(shù)據(jù)分散到不同的數(shù)據(jù)庫服務(wù)器、
例如蛤袒,一個簡單的電商網(wǎng)站熄云,包括用戶、商品妙真、訂單三個業(yè)務(wù)模塊缴允,我們可以將用戶數(shù)據(jù)、商品數(shù)據(jù)珍德、訂單數(shù)據(jù)分開放 到三臺不同的數(shù)據(jù)庫服務(wù)器上练般,而不是將所有數(shù)據(jù)都放在一臺數(shù)據(jù)庫服務(wù)器上。

image.png

雖然業(yè)務(wù)分庫能夠分散存儲和訪問壓力锈候,但同時也帶來了新的問題:
1)join操作問題
業(yè)務(wù)分庫后薄料,原本在同一個數(shù)據(jù)庫中的表分散到不同數(shù)據(jù)庫中,導(dǎo)致無法使用SQL的join查詢泵琳。
不同庫的數(shù)據(jù)無法聯(lián)表查詢摄职。只能通過id一步步子查詢。
(備注:不過現(xiàn)在很多系統(tǒng)中获列,推薦只使用子查詢谷市。盡量減少聯(lián)合查詢)
2)事務(wù)問題:業(yè)務(wù)分庫后,表分散到不同庫中击孩。無法通過事務(wù)統(tǒng)一修改
3)成本問題:業(yè)務(wù)分庫同時也帶來了成本的代價迫悠,本來1臺服務(wù)器搞定的事情,現(xiàn)在要3臺巩梢,如果考慮備份创泄,那就是2臺變成了6臺

  • 基于上述原因艺玲,對于小公司初創(chuàng)業(yè)務(wù),并不建議一開始就這樣拆分鞠抑,主要有幾個原因:
    1)初創(chuàng)業(yè)務(wù)存在很大的不確定性板驳,業(yè)務(wù)不一定能發(fā)展起來,業(yè)務(wù)開始的時候并沒有真正的存儲和訪問壓力碍拆,業(yè)務(wù)分庫并不能為業(yè)務(wù)帶來價值若治。
    2) 業(yè)務(wù)分庫后,表之間的join查詢感混、數(shù)據(jù)庫事務(wù)無法簡單實現(xiàn)了端幼。
    3) 業(yè)務(wù)分庫后,因為不同的數(shù)據(jù)要讀寫不同的數(shù)據(jù)庫弧满,代碼中需要增加根據(jù)數(shù)據(jù)類型映射到不同數(shù)據(jù)庫的邏輯婆跑,增加了工作量。而業(yè)務(wù)初創(chuàng)期間最重要的是快速實現(xiàn)庭呜、快速驗證滑进,業(yè)務(wù)分庫會拖慢業(yè)務(wù)節(jié)奏。

如果業(yè)務(wù)發(fā)展的真的很快募谎,后面進行分庫分表也不遲扶关。
業(yè)務(wù)分庫帶來的代碼和業(yè)務(wù)復(fù)雜可以通過增加人來解決,成本問題可以通過增加資金解決数冬。
單臺系統(tǒng)服務(wù)器性能沒有想象的弱节槐。一般來說,單臺數(shù)據(jù)庫服務(wù)器能夠支撐10萬用戶量量級的業(yè)務(wù)拐纱,初創(chuàng)業(yè)務(wù)從0發(fā)展到10萬級用戶铜异,并不是想象得那么快。

分表

將不同業(yè)務(wù)數(shù)據(jù)分散存儲到不同的數(shù)據(jù)庫服務(wù)器秸架,能夠支撐百萬甚至千萬用戶規(guī)模的業(yè)務(wù)揍庄。
如果業(yè)務(wù)繼續(xù)發(fā)展,同一業(yè)務(wù)的單表數(shù)據(jù)也會達到單臺數(shù)據(jù)庫服務(wù)器的處理瓶頸东抹。
例如蚂子,淘寶的幾億用戶數(shù)據(jù),如果全部存放在一臺數(shù)據(jù)庫服務(wù)器的一張表中府阀,肯定是無法滿足性能要求的缆镣,此時就需要對單表數(shù)據(jù)進行拆分芽突。

image.png

垂直分表:按列來分试浙。是表記錄數(shù)相同但包含不同的列。一張表300個字段寞蚌。從某一列拆分
水平分表:按行來分田巴。表的列相同但包含不同的行數(shù)據(jù)钠糊。一億條數(shù)據(jù),拆分為10張表壹哺。

單表切分后抄伍,是否需要將切分后的多個表分散在不同庫,根據(jù)實際效果來管宵。不強制要求單表切分后截珍,分散到不同庫中。因為箩朴,單表切分后岗喉,新的表即使同庫,也能帶來性能的很大提升炸庞,如果性能能滿足業(yè)務(wù)要求钱床,是可以不拆分為多臺庫的。
分表能夠有效地分散存儲壓力和帶來性能提升埠居,但和分庫一樣查牌,也會引入各種復(fù)雜性。

分表之垂直分表

垂直分表適合將表中某些不常用且占了大量空間的列拆分出去滥壕。
垂直分表主要帶來的是表操作數(shù)據(jù)增加纸颜。原本一次查詢的需要2次查詢。其復(fù)雜性相對較小绎橘。

分表之水平分表:

水平分表適合表行數(shù)特別大的表懂衩,有的公司要求單表行數(shù)超過5000萬就必須進行分表,數(shù)字作為參考不是絕對標準金踪,關(guān)鍵還是要看表的訪問性能浊洞。
對于一些比較復(fù)雜的表,可能超過1000萬就要分表了;
而對于一些簡單的表胡岔,即使存儲數(shù)據(jù)超過1億行法希,也可以不分表。
但不管怎樣靶瘸,當(dāng)看到表的數(shù)據(jù)量達到千萬級別時苫亦,作為架構(gòu)師就要警覺起來, 因為這很可能是架構(gòu)的性能瓶頸或者隱患怨咪。

水平分表帶來的復(fù)雜性屋剑,主要是:
第一點:路由
水平分表后,某條數(shù)據(jù)具體屬于哪個切分后的子表诗眨,需要增加路由算法進行計算唉匾,這個算法會引入一定的復(fù)雜性。

常見的路由算法有:

  • A.范圍路由:
    選取有序的數(shù)據(jù)列(例如,整形巍膘、時間戳等)作為路由的條件厂财,不同分段分散到不同的數(shù)據(jù)庫表中。以最常見的用戶ID為例峡懈,路由算法可以按照1000000的范圍大小進行 分段璃饱,1 ~ 999999放到數(shù)據(jù)庫1的表中,1000000 ~ 1999999放到數(shù)據(jù)庫2的表中肪康,以此類推荚恶。
    問題點在于:分段大小選取上,分段太小導(dǎo)致切分后子表數(shù)量過多磷支,增加維護復(fù)雜度裆甩;分表太大仍然存在性能問題。一般建議分段大小在100萬到2000萬之間(具體業(yè)務(wù)具體分析)齐唆。
    優(yōu)點在于:隨著數(shù)據(jù)的增加平滑地擴充新的表嗤栓。例如,現(xiàn)在的用戶是100萬箍邮,如果增加到1000萬茉帅,只需要增加新的表就可以了,原有的數(shù)據(jù)不需要動锭弊。
    缺點在于:分布不均勻堪澎,假如按照1000萬來進行分表,有可能某個分段實際存儲的數(shù)據(jù)量只有1000條味滞,而另外一個分段實際存儲的數(shù)據(jù)量有900萬條樱蛤。

  • B.Hash路由
    選取某個列(或者某幾個列組合也可以)的值進行Hash運算,然后根據(jù)Hash結(jié)果分散到不同的數(shù)據(jù)庫表中剑鞍。同樣以用戶ID為例昨凡,假如我們一開始就規(guī)劃了10個數(shù)據(jù)庫 表,路由算法可以簡單地用user_id % 10的值來表示數(shù)據(jù)所屬的數(shù)據(jù)庫表編號蚁署,ID為985的用戶放到編號為5的子表中便脊,ID為10086的用戶放到編號為6的字表中。
    問題點在于初始表數(shù)量的選取上光戈,表數(shù)量太多維護比較麻煩哪痰,表數(shù)量太少又可能導(dǎo)致單表性能存在問題。而用了Hash路由后久妆,增加字表數(shù)量是非常麻煩的晌杰, 所有數(shù)據(jù)都要重分布。
    Hash路由的優(yōu)缺點和范圍路由基本相反筷弦,Hash路由的優(yōu)點是表分布比較均勻肋演,缺點是擴充新的表很麻煩,所有數(shù)據(jù)都要重分布。

  • C.配置路由
    配置路由就是路由表惋啃,用一張獨立的表來記錄路由信息哼鬓。同樣以用戶ID為例监右,我們新增一張user_router表边灭,這個表包含user_id和table_id兩列,根據(jù)user_id就可以查詢對應(yīng)的table_id健盒。
    配置路由設(shè)計簡單绒瘦,使用起來非常靈活,尤其是在擴充表的時候扣癣,只需要遷移指定的數(shù)據(jù)惰帽,然后修改路由表就可以了。
    配置路由的缺點就是必須多查詢一次父虑,會影響整體性能;
    而且路由表本身如果太大(例如该酗,幾億條數(shù)據(jù)),性能同樣可能成為瓶頸士嚎,如果我們再次將路由表分庫分表呜魄,則又面臨一個死循環(huán)式的路由算法選擇問題。

第二點:join操作
水平分表后莱衩,數(shù)據(jù)分散在多個表中爵嗅,如果需要與其他表進行join查詢,需要在業(yè)務(wù)代碼或者數(shù)據(jù)庫中間件中進行多次join查詢笨蚁,然后將結(jié)果合并睹晒。

第三點:count()操作
水平分表后,雖然物理上數(shù)據(jù)分散到多個表中括细,但某些業(yè)務(wù)邏輯上還是會將這些表當(dāng)作一個表來處理伪很。
例如,獲取記錄總數(shù)用于分頁或者展示奋单,水平分表前用一個count()就能完成的操作是掰,在分表后沒那么簡單。
常見的處理方式有下面兩種:
count()相加:具體做法是在業(yè)務(wù)代碼或者數(shù)據(jù)庫中間件中對每個表進行count()操作辱匿,然后將結(jié)果相加键痛。這種方式實現(xiàn)簡單,缺點就是性能比較低匾七。例如絮短,水平分表后切分為20張
表,則要進行20次count(*)操作昨忆,如果串行的話丁频,可能需要幾秒鐘才能得到結(jié)果。
記錄數(shù)表:具體做法是新建一張表,假如表名為“記錄數(shù)表”席里,包含table_name叔磷、row_count兩個字段,每次插入或者刪除子表數(shù)據(jù)成功后奖磁,都更新“記錄數(shù)表”改基。
這種性能要優(yōu)于count()相加的方式,因為只需要一次簡單查詢咖为。
缺點是復(fù)雜度增加不少秕狰,對子表的操作要同步操作“記錄數(shù)表”,如果有一個 業(yè)務(wù)邏輯遺漏了躁染,數(shù)據(jù)就會不一致;且針對“記錄數(shù)表”的操作和針對子表的操作無法放在同一事務(wù)中進行處理鸣哀,異常的情況下會出現(xiàn)操作子表成功了而操作記錄數(shù)表失敗,同樣會導(dǎo) 致數(shù)據(jù)不一致吞彤。
此外我衬,記錄數(shù)表的方式也增加了數(shù)據(jù)庫的寫壓力,因為每次針對子表的insert和delete操作都要update記錄數(shù)表饰恕,所以對于一些不要求記錄數(shù)實時保持精確的業(yè)務(wù)挠羔,也可以通過后臺 定時更新記錄數(shù)表。定時更新實際上就是“count()相加”和“記錄數(shù)表”的結(jié)合懂盐,即定時通過count()相加計算表的記錄數(shù)褥赊,然后更新記錄數(shù)表中的數(shù)據(jù)。

第四點:order by操作
水平分表后莉恼,數(shù)據(jù)分散到多個子表中拌喉,排序操作無法在數(shù)據(jù)庫中完成,只能由業(yè)務(wù)代碼或者數(shù)據(jù)庫中間件分別查詢每個子表中的數(shù)據(jù)俐银,然后匯總進行排序尿背。
實現(xiàn)方法
和數(shù)據(jù)庫讀寫分離類似,分庫分表具體的實現(xiàn)方式也是“程序代碼封裝”和“中間件封裝”捶惜,但實現(xiàn)會更復(fù)雜田藐。讀寫分離實現(xiàn)時只要識別SQL操作是讀操作還是寫操作,通過簡單的判 斷SELECT吱七、UPDATE汽久、INSERT、DELETE幾個關(guān)鍵字就可以做到踊餐,而分庫分表的實現(xiàn)除了要判斷操作類型外景醇,還要判斷SQL中具體需要操作的表、操作函數(shù)(例如count函 數(shù))吝岭、order by三痰、group by操作等吧寺,然后再根據(jù)不同的操作進行不同的處理。例如order by操作散劫,需要先從多個庫查詢到各個庫的數(shù)據(jù)稚机,然后再重新order by才能得到最終的結(jié) 果。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末获搏,一起剝皮案震驚了整個濱河市赖条,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颜凯,老刑警劉巖谋币,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仗扬,死亡現(xiàn)場離奇詭異症概,居然都是意外死亡,警方通過查閱死者的電腦和手機早芭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門彼城,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人退个,你說我怎么就攤上這事募壕。” “怎么了语盈?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵舱馅,是天一觀的道長。 經(jīng)常有香客問我刀荒,道長代嗤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任缠借,我火速辦了婚禮干毅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘泼返。我一直安慰自己硝逢,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布绅喉。 她就那樣靜靜地躺著渠鸽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪柴罐。 梳的紋絲不亂的頭發(fā)上徽缚,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天,我揣著相機與錄音丽蝎,去河邊找鬼猎拨。 笑死膀藐,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的红省。 我是一名探鬼主播额各,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吧恃!你這毒婦竟也來了虾啦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤痕寓,失蹤者是張志新(化名)和其女友劉穎傲醉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呻率,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡硬毕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了礼仗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吐咳。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖元践,靈堂內(nèi)的尸體忽然破棺而出韭脊,到底是詐尸還是另有隱情,我是刑警寧澤单旁,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布沪羔,位于F島的核電站,受9級特大地震影響象浑,放射性物質(zhì)發(fā)生泄漏蔫饰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一融柬、第九天 我趴在偏房一處隱蔽的房頂上張望死嗦。 院中可真熱鬧,春花似錦粒氧、人聲如沸越除。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摘盆。三九已至,卻和暖如春饱苟,著一層夾襖步出監(jiān)牢的瞬間孩擂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工箱熬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留类垦,地道東北人狈邑。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像蚤认,于是被迫代替她去往敵國和親米苹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內(nèi)容