數(shù)據(jù)庫(kù)中間件為何不支持join
有網(wǎng)友對(duì)《假如讓你來設(shè)計(jì)數(shù)據(jù)庫(kù)中間件》一文中,數(shù)據(jù)庫(kù)中間件僅僅支持四類SQL存有疑問:
- partition key普通查詢
- partition key上的IN查詢
- 非partition key上的查詢
- 有限功能的排序+分頁(yè)查詢
這四類SQL就能滿足公司業(yè)務(wù)的需求么,這個(gè)結(jié)論是怎么來的?
看來《假如讓你來設(shè)計(jì)數(shù)據(jù)庫(kù)中間件》的架構(gòu)結(jié)論并不能讓刨根究底的網(wǎng)友們滿意,于是把13年底,需求調(diào)研的過程細(xì)節(jié)也說一說,作為一個(gè)一線架構(gòu)師,治學(xué)還是得嚴(yán)謹(jǐn)。
一、業(yè)務(wù)側(cè)的分庫(kù)后SQL需求
先說結(jié)論,通過初步的調(diào)研,發(fā)現(xiàn)58各業(yè)務(wù)線對(duì)有分庫(kù)需求的應(yīng)用場(chǎng)景為:
- partition key上的簡(jiǎn)單查詢:WHERE key=xxx AND xxx
- partition key上的IN查詢:WHERE key IN(xxx, yyy) AND xxx
- 非partition key上的簡(jiǎn)單查詢:WHERE notkey=xxx AND xxx
- 排序+分頁(yè)的需求:ORDER BY xxx OFFSET xxx LIMIT xxx
大部分需求集中在前三條,排序+分頁(yè)的需求由于分布式實(shí)現(xiàn)困難,各業(yè)務(wù)線往往也采用了一些限制或者變通手段實(shí)現(xiàn),例如:
- 建立索引表以避免遍歷庫(kù)再內(nèi)部排序
- 使用額外的id查詢條件來避免大數(shù)據(jù)量的查詢
調(diào)研結(jié)果顯示,各業(yè)務(wù)線暫沒有下列需求:
- 夸庫(kù)join
- 夸庫(kù)事務(wù)
- 夸庫(kù)子查詢
- 其他奇形怪狀的SQL
二、搜索研發(fā)部調(diào)研
從搜索研發(fā)部高級(jí)架構(gòu)師@longc 處了解到,暫時(shí)沒有數(shù)據(jù)庫(kù)分庫(kù)需求。
畫外音:@龍神 做搜索內(nèi)核,壓根瞧不起我這個(gè)用MySQL搞業(yè)務(wù)的人呀。
三、即時(shí)通訊部調(diào)研
和@sunx 進(jìn)行了溝通,幫幫技術(shù)部沒有水平分庫(kù),只有水平分表,業(yè)務(wù)需求為常見需求中的“partition key上的普通查詢”。
對(duì)于58幫幫的“用戶登陸表”,數(shù)據(jù)量較大,目前分為32個(gè)表,以u(píng)id作為partition key,所有的查詢都會(huì)帶上partition key,故可以直接定位到數(shù)據(jù)所屬的partition。
如上例,假設(shè)58幫幫對(duì)某數(shù)據(jù)量較大的表以id為partition key分了3個(gè)表,上游的所有查詢都會(huì)帶上id=xxx這個(gè)查詢條件(當(dāng)然,亦可以同時(shí)帶上其他查詢條件)。
畫外音:@玄姐 設(shè)計(jì)的系統(tǒng),架構(gòu)考慮得極其完善。
四、移動(dòng)研發(fā)部調(diào)研
從@liunz 了解到,無線分庫(kù)使用場(chǎng)景和幫幫技術(shù)部類似,都是“partition key 上的普通查詢”。
五、架構(gòu)部調(diào)研
從@liuzw 了解到,架構(gòu)部在imc,umc等服務(wù)使用水平分庫(kù),業(yè)務(wù)需求為常見需求中的“patition key 上的普通查詢”,“partition key上的IN查詢”,“非partition key上的查詢”。
對(duì)于“partition key上的IN查詢”,架構(gòu)部采用的是將各個(gè)partition key定位到相關(guān)的庫(kù),***將查詢結(jié)果集匯總,再返回上游的方式來實(shí)現(xiàn)。注意,如上圖所示,帶partition key的IN查詢并不一定會(huì)遍歷所有的庫(kù)。
對(duì)于“非partition key上的查詢”,根據(jù)不同的業(yè)務(wù),架構(gòu)部有兩種處理方式:
1. 方式一
業(yè)務(wù)方不需要精確數(shù)據(jù),隨機(jī)取一個(gè)庫(kù)的數(shù)據(jù),即可滿足業(yè)務(wù)方要求,例如“查詢10個(gè)有頭像的用戶”
當(dāng)業(yè)務(wù)方不需要關(guān)注結(jié)果集的精確性時(shí),可以隨機(jī)取一個(gè)庫(kù)查詢。
畫外音:這是一個(gè)很好的設(shè)計(jì),典型的“根據(jù)業(yè)務(wù)需求確定技術(shù)方案”的good case。
2. 方式二
業(yè)務(wù)方需要精確數(shù)據(jù),就必須遍歷所有的庫(kù),例如“查詢用戶名為shenjian的用戶”。
畫外音:uid的生成沒有采用“基因法”,非常遺憾。關(guān)于“基因法”的方案詳見《單KEY業(yè)務(wù),數(shù)據(jù)庫(kù)水平切分架構(gòu)實(shí)踐 | 架構(gòu)師之路》。
六、會(huì)員技術(shù)部調(diào)研
從@wangzt 了解到,會(huì)員技術(shù)部使用水平分庫(kù),調(diào)研結(jié)論里對(duì)分庫(kù)的四種SQL需求在業(yè)務(wù)中都有用到。
對(duì)“非partition key上的查詢”,除了使用架構(gòu)部使用的全庫(kù)查詢方案,會(huì)員技術(shù)部還是用了冗余數(shù)據(jù)法來解決這個(gè)問題:
這種查詢方式使用冗余數(shù)據(jù)來避免全庫(kù)查詢,缺點(diǎn)是可能存在數(shù)據(jù)一致性問題。
“夸庫(kù)分頁(yè)查詢”,會(huì)員技術(shù)部的處理方式是索引表:
使用訂單分庫(kù),買家的查詢查詢索引表,索引表的本質(zhì)也是冗余。
畫外音:關(guān)于“帖子業(yè)務(wù)的水平切分”的方案詳見《1對(duì)多業(yè)務(wù),數(shù)據(jù)庫(kù)水平切分架構(gòu)一次搞定 | 架構(gòu)師之路》。
七、支付平臺(tái)部調(diào)研
從@hudp 了解到,分庫(kù)的數(shù)據(jù)訪問,貨幣系統(tǒng)部所有的線上實(shí)時(shí)業(yè)務(wù)都必須攜帶partition key,故其訪問模式和即時(shí)通訊的數(shù)據(jù)訪問模式相同。
但對(duì)于支撐系統(tǒng)/統(tǒng)計(jì)需求,在分庫(kù)數(shù)據(jù)上,他們計(jì)劃引入cobar來解決他們的問題。
八、前端業(yè)務(wù)部調(diào)研
從@wangjk 了解到,前端業(yè)務(wù)部這邊,四種分庫(kù)SQL都有,對(duì)于夸庫(kù)分頁(yè),前端業(yè)務(wù)部這邊的業(yè)務(wù)上要求必須帶上一個(gè)特殊的id作為where字段,以避免拉取大量的數(shù)據(jù)重新排序。
九、結(jié)論
58如果要做數(shù)據(jù)庫(kù)中間件,一期支持四類SQL:
- partition key普通查詢
- partition key上的IN查詢
- 非partition key上的查詢
- 有限功能的排序+分頁(yè)查詢
能夠滿足業(yè)務(wù)線絕大部分分庫(kù)的需求。
【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】