需要存儲歷史數據時使用場景:
- 有一些表的數據量很大,比如一張用戶表,大約10億條記錄,50個字段,這種表,即使使用ORC壓縮,單張表的存儲也會超過100G,在HDFS使用雙備份或者三備份的話就更大一些。
- 表中的部分字段會被update更新操作,如用戶聯系方式,產品的描述信息,訂單的狀態等等。
- 需要查看某一個時間點或者時間段的歷史快照信息,比如,查看某一個訂單在歷史某一個時間點的狀態。
- 表中的記錄變化的比例和頻率不是很大,比如,總共有10億的用戶,每天新增和發生變化的有200萬左右,變化的比例占的很小。
針對上述場景的解決方案:
- 方案一:每天只留最新的一份,比如我們每天用Sqoop抽取最新的一份全量數據到Hive中。
- 方案二:每天保留一份全量的切片數據。
- 方案三:使用拉鏈表。
各種方案及可行性分析:
- 方案一:每天只留最新的一份,比如我們每天用Sqoop抽取最新的一份全量數據到Hive中。
實現方式:實現起來很簡單,每天drop掉前一天的數據,重新抽一份最新的。
優點:節省空間,使用方便,不用在選擇表的時候加一個時間分區什么的。
缺點:沒有歷史數據,要想翻舊賬只能通過其它方式,比如從流水表里面抽。 - 方案二:每天保留一份全量的切片數據。
實現方式:每天一份全量的切片是一種比較穩妥的方案,而且歷史數據也在。(類似於針對每天固定時間點的全量備份) - 方案三:使用拉鏈表。
拉鏈表在使用上基本兼顧了我們的需求。
首先它在空間上做了一個取舍,雖說不像方案一那樣占用量那么小,但是它每日的增量可能只有方案二的千分之一甚至是萬分之一。
其實它能滿足方案二所能滿足的需求,既能獲取最新的數據,也能添加篩選條件也獲取歷史的數據。
所以我們還是很有必要來使用拉鏈表的。
下面將詳盡解析如何創建拉鏈表
下面我們來舉個栗子詳細看一下拉鏈表。
我們先看一下在ORACLE數據庫里的U_USER表中的一張歷史表。
DROP TABLE U_USER; CREATE TABLE U_USER( U_DATE VARCHAR2(10), U_ID VARCHAR2(10), U_PHONE VARCHAR2(10) ); --- 插入 2017-01-01 初始狀態的第一批數據 INSERT INTO U_USER VALUES('2017-01-01','001','11111'); INSERT INTO U_USER VALUES('2017-01-01','002','22222'); INSERT INTO U_USER VALUES('2017-01-01','003','33333'); INSERT INTO U_USER VALUES('2017-01-01','004','44444'); COMMIT;
執行以上語句后,可得在2017-01-01這一天表中的數據為下圖所示: