天天看點

作為後端開發如何設計資料庫系列文章(二)設計大資料量表結構

上篇文章講解了傳統資料庫的一些設計注意點。

本篇為第二篇,在大資料量的情況下,如何去提前設計這個表結構,來達到一個比較好的效果。對于團隊,對于後續的維護和擴充都帶來更大的便利。

自增id

自增id還是可以有,但是不是必須的了。但是建議還是每張表中有一個自增id。 為什麼,還是那句話,做資料查詢,遷移,排序的時候,有着天然的一些優勢。

唯一辨別

這個辨別無論是token,還是其他例如訂單的訂單号或者其他唯一辨別都行。 重點是唯一,不隻是在單系統中唯一,而是需要在并發的情況,也能夠保持唯一。

關于分布式id的生成方案,網上已經有很多了,這裡就不重複了。谷歌搜尋搜尋,自己看下原理,跑跑demo,能夠滿足自己業務的最大并發情況下的唯一即可。

比如說你未來幾年的最大并發也就是100,搞個能支援在幾千并發下不會出現辨別重複的實作方案即可,并發幾萬,幾十萬,真的需要嗎?

後續如果真的能夠達到幾萬并發,那說明什麼?說明業務火爆了啊。難道還抽不出時間,抽不出人來做一個id生成方案的改造?這裡有比較重要的一點,不要太過超前設計,沒必要,也沒那個時間。

建立時間&修改時間

建立時間和修改時間還是要有的,而且建議時間精确到毫秒級别,在上一篇,我沒有說精确多少,那是因為并發不高,秒級完全夠了。但是在大資料量的情況下,可能一秒有幾十、幾百、上千、上萬的資料新增都是有可能的。那麼秒級在這種情況下完全就不夠看了,選擇毫秒級别是一個比較好的選擇。

分庫分表

前面的唯一辨別/建立時間可以說就是為了這步準備的。

但是怎麼來設計分庫分表,選擇什麼方式,範圍還是hash,選擇哪個字段,還是選擇幾個字段。平滑遷移還是停機遷移。

這些都沒有唯一答案。隻能是根據場景來區分不同的情況。下面舉幾個例子來進行一個講解,不是标準答案,同一個場景為了滿足不同的需求,也可能有不同的一個設計。

1:支付訂單的場景

例如,訂單每日新增千萬級,那麼在這個情況下。我們還需要區分一下。

1.1 訂單号包含了時間戳

那麼強烈建議按照時間次元進行分庫分表。 也強烈建議在訂單号中将時間戳放進去。

優點:

  • 單表的大小是可以預知的,一天多少訂單量,一個月多少訂單量

    非常便于水準擴充,後期如果想對整個分片叢集擴容時,隻需要添加庫表即可,不需要對已經存在的分片資料進行遷移。使用訂單号進行範圍查找時,可以快速定位查詢,避免了跨片查詢的問題。

缺點:

  • 最近的訂單會存在着熱點資料,可以通過其他方式進行解決,例如緩存等

1.2 訂單号不包含時間戳

不包含時間戳,你可以選擇建立時間來做範圍分片。 或者使用訂單号來做hash分片,也就是取模運算分片。

hash分片的缺點就是後期擴容會涉及到老資料的遷移,但是現在有一種方案可以避免該缺點,那就是使用虛節點,先占位,但不使用,需要的節點需要是2的次方個才行。大家可以去網上了解一下,這裡就不展開了。 另外一個缺點就是跨片查詢的性能問題,當查詢條件中沒有訂單号的時候,會無法定位到資料庫表,是以會周遊所有的庫表,進行查詢,再在記憶體中合并資料,取最小集傳回,在這種情況下,分庫分表反而會成為累贅。

其他一些分庫分表帶來的事務問題大家可以看看現在的一些分布式事務解決方案,都還挺不錯的。阿裡的Seata可以了解一下。

最後,分庫分表,并不是一定要分庫的,也可以隻分表,這樣很多分庫分表的問題就不存在了。 分庫分表還是要跟進實際的資料增長速度來評估,比如說,每年資料才幾十萬或者百萬,那麼沒有必要進行一個過渡設計,單表即可。等資料庫到了瓶頸,可以再考慮優化。

很多時候,瓶頸也不一定是在資料庫。

性能優化

在這裡,對于性能優化提一句,因為自己也剛完成一個性能優化的需求不久,提升性能2倍左右。這次優化完全沒有動資料庫。 主要優化點在:同步方法異步調用第三方服務、計算異步處理、批量單次調用、部分不變資料緩存 重點:拿資源(空間、線程)換時間

總結

當資料量大了之後,其實很多設計和傳統的資料庫還是沒有很大變化的。

主要是要考慮到資料量大之後,該表如果分庫分表,那麼怎麼設計更加合理一點,也許當下不需要分庫分表,但是可以給以後少埋點坑。

但是注意,還是那句話,不要過度設計,也不要不去設計。簡單的說,可以預估到以後的業務每日資料量新增是萬級幾十萬以上的,就可以考慮下以後的分表,但是當期并不需要做。 但如果是日增百萬千萬級别,那麼這個分庫分表肯定是當期就需要進行的。 假如是日增幾百幾千的表,那麼就不要花過多時間去考慮什麼分庫分表的方案了,真的用不上。

建議的一個提前思考時間,1年左右的思考次元設計比較好。即不會超前,也不會因為疊代了一兩次業務就有人提出,不知道哪個**設計的結構,又得重新來設計。

最後,能夠在技術方案時就明确的事情,絕不留到寫代碼的時候再去明确! 技術方案越清晰(注意:不是說超前設計,這裡面有個度,隻可意會不可言傳),寫代碼越輕松,團隊協作越流暢。