我們知道知乎的問題修改是可以追蹤其歷史記錄的,包括問題的標題的修改、問題的內容修改、問題關聯的Tag修改,都是可以記錄其歷史版本的。請問一下是怎樣設計MySQL來記錄問題的歷史版本的呢?還有,假如知乎的問題是同時允許多人修改的(像Quora那樣的),那麼知乎會怎麼樣解決多人同時編輯的「協作衝突」問題呢?嚴重跪求各位大俠出來給小弟解答!謝謝!


查看了一下和知乎同樣功能的私有化問答社區WeCenter的資料庫Schema,發現是user_history_action_data表存儲了每個版本的完整記錄,然後程序(PHP代碼)再執行diff演算法渲染出差異部分。這樣做的好處是資料庫設計簡單,程序簡單,性能稍微好一點(知乎肯定用了緩存,所以性能差別沒有那麼明顯),壞處就是資料庫佔用空間更大。

然後我又看了一下維基百科源碼(MediaWiki),它的設計仍然是在text這張表用blob類型完整記錄了每個版本,並沒有看到什麼比較亮眼的設計。可能也是因為這類PHP源碼為了兼顧性能和易用性以及二次開發複雜度,所以沒有做過多設計。

上面兩張圖請無視亂碼部分,old_id=3和old_id=4的情況下,兩個版本都是完整記錄。猜測程序部分也是執行diff演算法渲染,也許會有一個類似於模版緩存的功能提升一下性能,避免每次查看歷史記錄的時候都實時執行diff演算法計算差異部分。


知乎如何實現的我不清楚,不過你可以參考下wikipedia的database設計。http://forums.mysql.com/read.php?153,246205,246205
非常抱歉!對於知乎的修改記錄怎麼存儲的真不清楚,要是分析的話,只能猜測與談個人想法,為此與提問朋友的原意就違背了,邀請 知乎的技術人員回答吧! 另外有不少知乎類似網站的開源版本,也可以看下,應該大家差不多的....


只需要記錄一個版本號就行了,每次用戶點擊修改時,分配一個版本號;提交修改後,判斷要提交的版本號是否比先前的版本號高,如果低的話,就不讓提交,如果高的話就提交成功。
每一次「修改」都是一條新記錄 每次列出修改日誌時在相鄰兩條記錄之間作比對,高亮差異部分 我猜的


會不會是這樣設計的: 知乎有三個是會追蹤修改記錄,分別是問題、補充說明、話題,回答是不追蹤修改記錄的,我猜,問題、補充說明和話題應該是分三個表存儲的,當有新的問題被添加時,系統會將問題內容插入到問題表中,當問題被修改時,不是對問題記錄進行更新(UPDATE)操作,而是將修改後的問題重新插入(INSERT INTO)到問題表中,補充說明和話題也是一樣。然後,在顯示的時候,根據問題的ID取出最後被修改的那條記錄顯示出來。
Slowly changing dimension可以實現知乎的這種效果。
作為參考,Mediawiki會在出現衝突的時候不讓後提交的人提交
oracle本身帶有回溯功能,有一些wiki使用的svn來做為數據存儲,這是一個不錯的方式。我猜測zhihu用的是自己設計資料庫表的方式實現的
推薦閱讀:
相關文章