打開朋友圈摹恰,手指向下滑了幾下俗慈,又一“廣告狗”闺阱!點(diǎn)擊頭像 ---- 右上角 ---- 設(shè)置朋友圈權(quán)限 ---- 不看他的朋友圈酣溃。一套動(dòng)作下來赊豌,如行云流水碘饼,動(dòng)作利索。再下拉刷新住涉,不到一秒的時(shí)間秆吵,廣告沒了纳寂,朋友圈再度一片清新氣象~
慢著毙芜,別走!我不是標(biāo)題黨隘冲!這就奔主題0笮邸罗珍!
”不到一秒的時(shí)間“覆旱,重新刷新核无,剛剛屏蔽的消息就沒了噪沙,作為程序猿已慢,當(dāng)然好奇這是如何實(shí)現(xiàn)的,腦海里冒出了一個(gè)問題:”微信朋友圈的數(shù)據(jù)是如何存儲(chǔ)和拉取的膜楷?“
首先假設(shè)A赌厅,B特愿,C揍障,D的關(guān)系如下:
當(dāng)A發(fā)布了一條朋友圈癌蚁,B評(píng)論了A的朋友圈,來分析下微信朋友圈的設(shè)計(jì)需求:
-
A發(fā)布的消息誰能看伐蒂?
- A的好友能查看
- 非屏蔽A的好友圈的好友能查看
- 非被A屏蔽的好友能查看
-
B在A的消息中的評(píng)論和贊誰能看饿自?
- A和C的共同好友能查看
帶著問題,我想到了兩種方案:
方案一:
用最愚蠢的方法,每個(gè)用戶都有一張表來保存自己的朋友圈的消息总放,當(dāng)A發(fā)布一條消息時(shí)好爬,除了屏蔽的和被屏蔽的的好友炬搭,把該消息插入A的所有好友中融虽。同理有额,評(píng)論和贊都插入A和B的共同好友中。
- 優(yōu)點(diǎn):易實(shí)現(xiàn)句狼;查詢快。
- 缺點(diǎn):數(shù)據(jù)量大筹吐,如果一個(gè)用戶有幾百的好友,發(fā)布一條消息就得存儲(chǔ)幾百份洋侨,單從這點(diǎn),這方案就不可取了。更新數(shù)據(jù)量龐大聊疲,如果A把消息刪除了获洲,要通知所有好友刪除... 不愿再想下去了...
方案二:
否定了方案一后最爬,我想到了用索引。每個(gè)用戶的朋友圈是維護(hù)了一條索引鏈和自己發(fā)布的消息表固歪。A發(fā)布了一條消息,保存到自己的消息表中,除了屏蔽的和被屏蔽的的好友,把該消息的索引插入所有好友的索引鏈中。當(dāng)如C打開朋友圈時(shí)晌畅,C按照索引從每個(gè)好友的消息表中拉取數(shù)據(jù)。同理,評(píng)論和贊也如此反粥。
- 優(yōu)點(diǎn):相對(duì)方案一郑气,數(shù)據(jù)量明顯減少忙芒。
- 缺點(diǎn):查詢慢,每次刷新都從好友的表中查詢讳侨,如果有幾百個(gè)好友呵萨,是不可能做到”不到一秒時(shí)間“的!
因?yàn)楫?dāng)時(shí)是憑空想的跨跨,當(dāng)然很多細(xì)節(jié)都沒考慮到潮峦,但看上去好像能這樣實(shí)現(xiàn),只是不可取而已勇婴。其中大家可以注意到我加粗的文字忱嘹,我犯了一個(gè)錯(cuò)誤:把除了屏蔽的和被屏蔽的的好友與其他好友區(qū)分開來,從而導(dǎo)致了數(shù)據(jù)存儲(chǔ)和加載的復(fù)雜度大大提高耕渴。我要考慮屏蔽或取消屏蔽時(shí)服務(wù)器如何處理消息與用戶的關(guān)系拘悦,并如何通知客戶端更新等等問題,結(jié)果想的東西越來越復(fù)雜橱脸,各種數(shù)據(jù)縱橫交錯(cuò)础米,自己都不敢再想下去了。因?yàn)橐坏?fù)雜了就是錯(cuò)誤的添诉!這句話其實(shí)是我的好友跟我說的:”編程時(shí)椭盏,如果一個(gè)問題你覺得很復(fù)雜,那就永遠(yuǎn)無法解決吻商√图眨”
其實(shí)不但是編程,任何事情都這樣艾帐,如果你先入為主地認(rèn)為它復(fù)雜乌叶,到最后你肯定解決不了這件事情。并且柒爸,如果你處理事情時(shí)准浴,使用的方法越來越復(fù)雜,這個(gè)方法肯定是錯(cuò)誤或愚蠢的捎稚!肯定有更好的方法可以優(yōu)雅地解決問題乐横。
但由于我的能力和知識(shí)有限,并想不出更好的方案來處理朋友圈的數(shù)據(jù)存儲(chǔ)和拉取問題今野,哈哈葡公。但我會(huì)查閱資料。直到我看到了下面這篇文章才恍然大悟条霜,果然催什,很優(yōu)雅!很簡單T姿蒲凶!
看了上面的文章后气筋,我自己也整理了一遍:
下面對(duì)上圖分析下:
關(guān)系:
A,B旋圆,C互相為好友宠默,A與D為好友。
核心表:
- 發(fā)布表:所有用戶共用(注意灵巧,公用不代表存儲(chǔ)在同一個(gè)服務(wù)器)
- 相冊(cè)表:每個(gè)用戶都有自己獨(dú)立的相冊(cè)
- 評(píng)論或贊表:所有用戶共用搀矫,跟發(fā)布表是多對(duì)一的關(guān)系
- 時(shí)間線表:每個(gè)用戶都有自己獨(dú)立的時(shí)間線,也就是朋友圈啦
流程:
- 假設(shè)A發(fā)布了一條朋友圈孩等,服務(wù)器會(huì)做兩件事:
- 把該消息存儲(chǔ)到發(fā)布表中
把消息插入每個(gè)好友的時(shí)間線上艾君,不區(qū)分屏蔽或被屏蔽的好友采够。
B評(píng)論或贊了A的朋友圈肄方,服務(wù)器也是做兩件事:
- 把該評(píng)論或贊存儲(chǔ)到評(píng)論表或贊表中
關(guān)聯(lián)對(duì)應(yīng)的消息(其實(shí)這步在1中做了,為了更清晰分開講)
C和D打開朋友圈
- 根據(jù)C的時(shí)間線向發(fā)布表請(qǐng)求數(shù)據(jù)
- 如果是共同好友蹬癌,加載評(píng)論和贊权她,否則不加載
整個(gè)流程下來,邏輯非常清晰逝薪,思路非常簡單隅要!當(dāng)然,實(shí)際的設(shè)計(jì)不會(huì)這么簡單董济,還有很多細(xì)節(jié)步清,如數(shù)據(jù)緩存,服務(wù)器部署等等要考慮和處理虏肾,這里只是簡述了基本的工作流程而已廓啊。
相信聰明的你已注意到,上面的文章根本就沒討論屏蔽與非屏蔽的問題封豪,不是忘了谴轮,而是沒必要。后面我想了想吹埠,因?yàn)橄⒒蛴押梦覀兛梢赃x擇屏蔽或取消屏蔽第步,如果每次操作都要通知服務(wù)器進(jìn)行增刪,那效率不是很低缘琅?粘都!所以應(yīng)該是消息都會(huì)存儲(chǔ)到每個(gè)用戶的時(shí)間線上(這點(diǎn)我應(yīng)該早點(diǎn)想到的...),至于是服務(wù)器查詢時(shí)跳過屏蔽的消息刷袍,還是客戶端選擇性顯示就不得而知了驯杜。
由于本人是搞客戶端的,后端的技術(shù)我也不會(huì)哈哈做个,上面的內(nèi)容只是突然好奇的所思與所想鸽心,所以難免會(huì)有錯(cuò)誤的論述滚局。若有錯(cuò),歡迎指正顽频。
低頭看下表藤肢,從開始想這個(gè)問題到寫完這篇文章,用了5個(gè)有多的小時(shí)糯景,如果覺得有幫助或有趣的話嘁圈,點(diǎn)下紅心唄~