掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
一、什么是多對多關(guān)系

網(wǎng)站設(shè)計制作過程拒絕使用模板建站;使用PHP+MYSQL原生開發(fā)可交付網(wǎng)站源代碼;符合網(wǎng)站優(yōu)化排名的后臺管理系統(tǒng);網(wǎng)站設(shè)計制作、成都網(wǎng)站制作收費合理;免費進(jìn)行網(wǎng)站備案等企業(yè)網(wǎng)站建設(shè)一條龍服務(wù).我們是一家持續(xù)穩(wěn)定運營了10余年的創(chuàng)新互聯(lián)建站網(wǎng)站建設(shè)公司。
所謂的“多對多”,來自數(shù)據(jù)庫設(shè)計中的“實體-關(guān)系”ER模型,用來描述實體之間的關(guān)聯(lián)關(guān)系,一個學(xué)生可以選修多個課程,一個課程可以被多個學(xué)生選修,這里學(xué)生與課程時間的關(guān)系,就是多對多關(guān)系。
二、好友中心業(yè)務(wù)分析
好友關(guān)系主要分為兩類,弱好友關(guān)系與強(qiáng)好友關(guān)系,兩類都有典型的互聯(lián)網(wǎng)產(chǎn)品應(yīng)用。
弱好友關(guān)系的建立,不需要雙方彼此同意:
微博粉絲是一個典型的弱好友關(guān)系應(yīng)用。
強(qiáng)好友關(guān)系的建立,需要好友關(guān)系雙方彼此同意:
QQ好友是一個典型的強(qiáng)好友關(guān)系應(yīng)用。
好友中心是一個典型的多對多業(yè)務(wù),一個用戶可以添加多個好友,也可以被多個好友添加,其典型架構(gòu)為:
三、弱好友關(guān)系-元數(shù)據(jù)簡版實現(xiàn)
通過弱好友關(guān)系業(yè)務(wù)分析,很容易了解到,其核心元數(shù)據(jù)為:
- guanzhu(uid, guanzhu_uid);
- fensi(uid, fensi_uid);
其中:
需要強(qiáng)調(diào)的是,一條弱關(guān)系的產(chǎn)生,會產(chǎn)生兩條記錄,一條關(guān)注記錄,一條粉絲記錄。
例如:用戶A(uid=1)關(guān)注了用戶B(uid=2),A多關(guān)注了一個用戶,B多了一個粉絲,于是:
(1) 如何查詢一個用戶關(guān)注了誰呢?
回答:在guanzhu的uid上建立索引:
- select * from guanzhu where uid=1;
即可得到結(jié)果,1關(guān)注了2。
(2) 如何查詢一個用戶粉了誰呢?
回答:在fensi的uid上建立索引:
- select * from fensi where uid=2;
即可得到結(jié)果,2粉了1。
四、強(qiáng)好友關(guān)系-元數(shù)據(jù)實現(xiàn)一
通過強(qiáng)好友關(guān)系業(yè)務(wù)分析,很容易了解到,其核心元數(shù)據(jù)為:
- friend(uid1, uid2);
其中:
(1) uid=1的用戶添加了uid=2的用戶,雙方都同意加彼此為好友,這個強(qiáng)好友關(guān)系,在數(shù)據(jù)庫中應(yīng)該插入記錄{1, 2}還是記錄{2,1}呢?
回答:都可以
為了避免歧義,可以人為約定,插入記錄時uid1的值必須小于uid2。
例如:有uid=1,2,3三個用戶,他們互為強(qiáng)好友關(guān)系,那邊數(shù)據(jù)庫中可能是這樣的三條記錄
- {1, 2}
- {2, 3}
- {1, 3}
(2) 如何查詢一個用戶的好友呢?
回答:假設(shè)要查詢uid=2的所有好友,只需在uid1和uid2上建立索引,然后:
- select * from friend where uid1=2
- union
- select * from friend where uid2=2
即可得到結(jié)果。
作業(yè),為何不使用:
- select * from friend uid1=2 or uid2=2
五、強(qiáng)好友關(guān)系-元數(shù)據(jù)實現(xiàn)二
強(qiáng)好友關(guān)系是弱好友關(guān)系的一個特例,A和B必須互為關(guān)注關(guān)系(也可以說,同時互為粉絲關(guān)系),即也可以使用關(guān)注表和粉絲表來實現(xiàn):
- guanzhu(uid, guanzhu_uid);
- fensi(uid, fensi_uid);
例如:用戶A(uid=1)和用戶B(uid=2)為強(qiáng)好友關(guān)系,即相互關(guān)注:
用戶A(uid=1)關(guān)注了用戶B(uid=2),A多關(guān)注了一個用戶,B多了一個粉絲,于是:
同時,用戶B(uid=2)也關(guān)注了用戶A(uid=1),B多關(guān)注了一個用戶,A多了一個粉絲,于是:
六、數(shù)據(jù)冗余是實現(xiàn)多對多關(guān)系水平切分的常用實踐
對于強(qiáng)好友關(guān)系的兩類實現(xiàn):
在數(shù)據(jù)量小時,看似無差異,但數(shù)據(jù)量大時,數(shù)據(jù)冗余的優(yōu)勢就體現(xiàn)出來了:
數(shù)據(jù)冗余,是多對多關(guān)系,在數(shù)據(jù)量大時,數(shù)據(jù)水平切分的常用實踐。
七、如何進(jìn)行數(shù)據(jù)冗余
接下來的問題轉(zhuǎn)化為,好友中心服務(wù)如何來進(jìn)行數(shù)據(jù)冗余,常見有三種方法。
方法一:服務(wù)同步冗余
顧名思義,由好友中心服務(wù)同步寫冗余數(shù)據(jù),如上圖1-4流程:
優(yōu)點:
缺點:
如果系統(tǒng)對處理時間比較敏感,引出常用的第二種方案
方法二:服務(wù)異步冗余
數(shù)據(jù)的雙寫并不再由好友中心服務(wù)來完成,服務(wù)層異步發(fā)出一個消息,通過消息總線發(fā)送給一個專門的數(shù)據(jù)復(fù)制服務(wù)來寫入冗余數(shù)據(jù),如上圖1-6流程:
優(yōu)點:
缺點:
如果想解除“數(shù)據(jù)冗余”對系統(tǒng)的耦合,引出常用的第三種方案
方法三:線下異步冗余
數(shù)據(jù)的雙寫不再由好友中心服務(wù)來完成,而是由線下的一個服務(wù)或者任務(wù)來完成,如上圖1-6流程:
優(yōu)點:
缺點:
上述三種方案各有優(yōu)缺點,可以結(jié)合實際情況選取。
數(shù)據(jù)冗余固然能夠解決多對多關(guān)系的數(shù)據(jù)庫水平切分問題,但又帶來了新的問題,如何保證正表T1與反表T2的數(shù)據(jù)一致性呢?
八、如何保證數(shù)據(jù)的一致性
上一節(jié)的討論可以看到,不管哪種方案,因為兩步操作不能保證原子性,總有出現(xiàn)數(shù)據(jù)不一致的可能,高吞吐分布式事務(wù)是業(yè)內(nèi)尚未解決的難題,此時的架構(gòu)優(yōu)化方向,并不是完全保證數(shù)據(jù)的一致,而是盡早的發(fā)現(xiàn)不一致,并修復(fù)不一致。
最終一致性,是高吞吐互聯(lián)網(wǎng)業(yè)務(wù)一致性的常用實踐。更具體的,保證數(shù)據(jù)最終一致性的方案有三種。
方法一:線下掃面正反冗余表全部數(shù)據(jù)
如上圖所示,線下啟動一個離線的掃描工具,不停的比對正表T1和反表T2,如果發(fā)現(xiàn)數(shù)據(jù)不一致,就進(jìn)行補(bǔ)償修復(fù)。
優(yōu)點:
缺點:
有沒有只掃描“可能存在不一致可能性”的數(shù)據(jù),而不是每次掃描全部數(shù)據(jù),以提高效率的優(yōu)化方法呢?
方法二:線下掃描增量數(shù)據(jù)
每次只掃描增量的日志數(shù)據(jù),就能夠極大提高效率,縮短數(shù)據(jù)不一致的時間窗口,如上圖1-4流程所示:
當(dāng)然,我們還是需要一個離線的掃描工具,不停的比對日志log1和日志log2,如果發(fā)現(xiàn)數(shù)據(jù)不一致,就進(jìn)行補(bǔ)償修復(fù)
優(yōu)點:
缺點:
有沒有實時檢測一致性并進(jìn)行修復(fù)的方法呢?
方法三:實時線上“消息對”檢測
這次不是寫日志了,而是向消息總線發(fā)送消息,如上圖1-4流程所示:
這次不是需要一個周期掃描的離線工具了,而是一個實時訂閱消息的服務(wù)不停的收消息。
假設(shè)正常情況下,msg1和msg2的接收時間應(yīng)該在3s以內(nèi),如果檢測服務(wù)在收到msg1后沒有收到msg2,就嘗試檢測數(shù)據(jù)的一致性,不一致時進(jìn)行補(bǔ)償修復(fù)
優(yōu)點:
缺點:
however,技術(shù)方案本身就是一個投入產(chǎn)出比的折衷,可以根據(jù)業(yè)務(wù)對一致性的需求程度決定使用哪一種方法。
九、總結(jié)
文字較多,希望盡量記住如下幾點:
【本文為專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請聯(lián)系原作者】

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流