有如下幾種解決思路:
查出所有的問答數(shù)據(jù),然后調(diào)用用戶服務進行拼裝數(shù)據(jù),再根據(jù)過濾字段state字段進行過濾,最后進行排序和分頁并返回。
這種方式能夠保證數(shù)據(jù)的準確性和完整性,但是性能影響非常大,不建議使用。
查詢出state字段符合/不符合的UserId,在查詢問答數(shù)據(jù)的時候使用in/not in進行過濾,排序,分頁等。過濾出有效的問答數(shù)據(jù)后,再調(diào)用用戶服務獲取數(shù)據(jù)進行組裝。
這種方式明顯更優(yōu)雅點。筆者之前在某個項目的特殊場景中就是采用過這種方式實現(xiàn)。
跨庫事務(分布式事務)的問題
按業(yè)務拆分數(shù)據(jù)庫之后,不可避免的就是“分布式事務”的問題。以往在代碼中通過spring注解簡單配置就能實現(xiàn)事務的,現(xiàn)在則需要花很大的成本去保證一致性。這里不展開介紹,
感興趣的讀者可以自行參考《分布式事務一致性解決方案》,鏈接地址:
http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistency
垂直分庫總結(jié)和實踐建議
本篇中主要描述了幾種常見的拆分方式,并著重介紹了垂直分庫帶來的一些問題和解決思路。讀者朋友可能還有些問題和疑惑。
1. 我們目前的數(shù)據(jù)庫是否需要進行垂直分庫?
根據(jù)系統(tǒng)架構和公司實際情況來,如果你們的系統(tǒng)還是個簡單的單體應用,并且沒有什么訪問量和數(shù)據(jù)量,那就別著急折騰“垂直分庫”了,否則沒有任何收益,也很難有好結(jié)果。
切記,“過度設計”和“過早優(yōu)化”是很多架構師和技術人員常犯的毛病。
2. 垂直拆分有沒有原則或者技巧?
沒有什么黃金法則和標準答案。一般是參考系統(tǒng)的業(yè)務模塊拆分來進行數(shù)據(jù)庫的拆分。比如“用戶服務”,對應的可能就是“用戶數(shù)據(jù)庫”。但是也不一定嚴格一一對應。有些情況下,數(shù)據(jù)庫拆分的粒度可能會比系統(tǒng)拆分的粒度更粗。筆者也確實見過有些系統(tǒng)中的某些表原本應該放A庫中的,卻放在了B庫中。有些庫和表原本是可以合并的,卻單獨保存著。還有些表,看起來放在A庫中也OK,放在B庫中也合理。
如何設計和權衡,這個就看實際情況和架構師/開發(fā)人員的水平了。
3. 上面舉例的都太簡單了,我們的后臺報表系統(tǒng)中join的表都有n個了,
分庫后該怎么查?
有很多朋友跟我提過類似的問題。其實互聯(lián)網(wǎng)的業(yè)務系統(tǒng)中,本來就應該盡量避免join的,如果有多個join的,要么是設計不合理,要么是技術選型有誤。請自行科普下OLAP和OLTP,報表類的系統(tǒng)在傳統(tǒng)BI時代都是通過OLAP數(shù)據(jù)倉庫去實現(xiàn)的(現(xiàn)在則更多是借助離線分析、流式計算等手段實現(xiàn)),而不該向上面描述的那樣直接在業(yè)務庫中執(zhí)行大量join和統(tǒng)計。