GreenPlum學習筆記:create table創建表


  二維表同樣是GP中重要的存儲數據對象,為了更好的支持數據倉庫海量數據的訪問,GP的表可以分成:

  • 面向行存儲的普通堆積表
  • 面向列存儲的AOT表(append only table)

  當然AOT表也可以是按行存儲的,但是按列存儲必須是AOT表。這樣,我們在設計應用上可以獲得相當的靈活性。比如經常需要更新的數據,或者較小的維度數據,應該使用普通堆積表存儲。

  例子:

create table tmp_001( month_id numeric(8), serv_id numeric(30), cust_id numeric(30) ) with ( appendonly=true, compresslevel=5, orientation=column, compresstype=zlib, oids=false ) distributed by (month_id,serv_id)

1.分布鍵(哈希鍵)

  • distributed by (a) 指定a字段為分布鍵
  • distributer randomly 隨機分布

注意:

  • 未指定分布鍵,默認表的主鍵為分布鍵,若表沒有主鍵,則默認把第一列當作哈希鍵
  • 分布鍵可以被定義為一個或多個
  • 分布鍵必須是唯一鍵
  • 不能修改分布鍵,且哈希鍵的列不能update
  • 一個表只能定義一個唯一鍵,且主鍵和唯一鍵必須作為哈希鍵
  • 數值重復度低,保證數據均勻分布
  • 防止數據傾斜,布爾值不適合,float、double數據類型也不適合,interger、varchar比較好
  • 大表經常做連接時,選擇相同的分布鍵,避免跨節點進行join
  • 盡量不用序列號,無意義

2.AOT 指定按列分布

  • appendonly=true  指定是否只append追加
  • compresslevel=5 zlib壓縮級別 1-9共9個級別 9壓縮最大
  • orientation=column 指定是否按列存儲
  • compresstype=zlib GP提供兩種壓縮算法:zlib和quicklz
  • oids=false 對象標識符 不分配

3.其他注意

  與其它數據庫相比,GP的表最大的不同是它一定是分區的,也就是表中的所有記錄都會依據相關算法打散,分布到所有的segment當中,從而在充分利用硬件資源的同時,最大化訪問數據的IO,這種特性對於數據倉庫應用是非常有幫助的。

  GP提供兩種打散數據的算法,一種是Hash算法:distributed by (serv_id),在定義表的時候,通過distributed by指定表中的某個列或者某個列的組合作為Hash鍵,相同Hash鍵的記錄會放在同一個segment當中。所以,GP建議一般選擇記錄分布均勻的鍵作為Hash鍵使用,從而保證表中的記錄可以均勻分布到所有segment上。如果表上定義了主鍵或者唯一鍵,則這些鍵值列必須作前導列出現在分布鍵當中,並且放在第一位。

   如果定義表的時候,沒有指定distributed子句,系統使用第一個列作為Hash鍵使用。

  另一種數據打散的算法是平均分配法(ROUND-ROBIN),distributed randomly, 假設有三個段,那么這種算法會把第一條記錄放在段1, 第二條記錄放在段2,第三條記錄放在段3,第四條記錄放在段1,以此類推,直到所有記錄發放完為止。這種算法比較適合表中的字段存在嚴重數據傾斜的情況。

  在數據倉庫中,對於存儲海量少變化歷史數據的事實表的訪問,會產生大量IO。這些表除了記錄多外(縱向),同時也很寬。比如幾十列,甚至上百列的表也很常見。但是在進行數據分析和挖掘過程中,我們可能只用到這些列的很小一部分內容,而傳統的按行存儲的表,在訪問時總是會訪問記錄中的所有列,導致很多無效IO,當由於表橫向尺寸過大,按行存儲的表還會出現行鏈接,這會使無效IO的問題更嚴重。在GP中,對於這種情況應該考慮使用面向列存儲的AOT表,從而大幅高IO效率,獲取數據查詢性能的收益。

   現在硬件系統往往IO效率跟不上CPU處理的速度,而數據倉庫應用恰恰是IO敏感型的應用,所以很多數據倉庫系統上,會看到CPU很閑,但是出現大量IO等待的情況。所以通過壓縮,尤其是面向列壓縮,允許我們犧牲一定的CPU效率進一步換取IO效率,提高系統的的吞吐量。

  GP的AOT表允許使用兩種壓縮算法,一種是ZLIB,它的壓縮率較高,對CPU的消耗較多,GP中可以指定1到9共9個級別。1的壓縮比最小,9最大。另一種算法是QUICKLZ,它的壓縮比小,能設置1,造成的CPU負載也比ZLIB小。

  AOT表雖然查詢和加載數據的效率很高,但是如它的名字那樣它只能支持select,insert,truncate操作,不支持update和delete操作。所以它只適合存放經過處理基本最終無變化的歷史數據,用來提供高效的查詢訪問。

  從數據數據存放的生命周期看,前面介紹的表都稱之為永久表,這些表的記錄不會因為事務的結束和會話的斷開而消失。而業務中,我們經常要使用到臨時數據集合,如果用永久表存放中間結果,一方面是在並發環境中數據不安全,另一方面頻繁的刪除表中的記錄或者刪除表,會導致大量碎片,在字典層面造成瓶頸。因此GP也支持臨時表,不同連接共享相同的表結構。比如下面的例子:

CREATE TEMP TABLE SALES_TMP (PROD_ID numeric NOT NULL , CUST_ID numeric NOT NULL , TIME_ID DATE NOT NULL , CHANNEL_ID numeric NOT NULL , PROMO_ID numeric NOT NULL , QUANTITY_SOLD numeric(10,2) NOT NULL , AMOUNT_SOLD numeric(10,2) NOT NULL) on commit preserve rows distributed randomly;
CREATE TEMP TABLE SALES (PROD_ID numeric NOT NULL , CUST_ID numeric NOT NULL , TIME_ID DATE NOT NULL , CHANNEL_ID numeric NOT NULL , PROMO_ID numeric NOT NULL , QUANTITY_SOLD numeric(10,2) NOT NULL , AMOUNT_SOLD numeric(10,2) NOT NULL) on commit delete rows distributed by (prod_id,cust_id,time_id,channel_id,promo_id);

  例子一是事務內有效,連接會話間數據獨立。完成事務后數據保留,只有連接會話斷開后數據才消失。

  例子二是事務內有效,也就是提交事務后(commit)數據就會消失。

  如果臨時表的名字與永久表名字重復,臨時表的訪問優先。

  除了普通表以外,GP還支持超大表進行分區應用,為我們的提高數據訪問效率的同時,也提高應用的靈活型。它可以支持RANGE分區,LIST分區,以及靈活的復合分區(RANGE-LIST,RANGE-RANGE,LIST-RANGE,LIST-LIST,以及更多層次的分區,比如三層分區),GP的分區是基於segment基礎之上的。每個分區的數據同樣會打散分布到每個segment中,當where條件上出現分區鍵時,它會進行分區裁剪,減少IO。需要注意的是,目前GreenPlum還只支持靜態分區裁剪,所以如果希望用到分區裁剪,請在Where條件中使用事實表的分區鍵作為條件。


 END 2018-08-01 18:17:13 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM