當前位置:網站首頁>如何利用數倉創建時序錶

如何利用數倉創建時序錶

2022-06-23 23:55:36華為雲開發者聯盟

摘要:怎麼快速上手,創建適合自己業務的時序錶,怎樣使用才能真正發揮時序錶的優勢。

本文分享自華為雲社區《GaussDB(DWS)帶你走近IoT時代-時序錶建錶最佳實踐》,作者:AndyCao。

創建第一張時序錶

我們首先來介紹一下如何創建一張時序錶

語法格式

CREATE TABLE [ IF NOT EXISTS ] table_name
({ column_name data_type [ kv_type ] 
    | LIKE source_table [like_option [...] ] }
}
    [, ... ])
[ WITH ( {storage_parameter = value}  [, ... ] ) ]

[ TABLESPACE tablespace_name ]
[ DISTRIBUTE BY  HASH ( column_name [,...])]
[ TO { GROUP groupname | NODE ( nodename [, ... ] ) } ]
[ table_partitioning_clauses ]
[ PARTITION BY { 
        {RANGE (partition_key) ( partition_less_than_item [, ... ] )} 
 } [ { ENABLE | DISABLE } ROW MOVEMENT ] ]; 

其中like選項like_option為:{ INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | PARTITION | RELOPTIONS | DISTRIBUTION | ALL }

時序錶的建錶語法,在很大程度上繼承了行存和列存的語法,降低了用戶的學習成本,能够更容易理解和使用。我們上篇博客中介紹到,將時序錶的列分為三種kv_type類型(tag、field、time),那麼如何將對應的列指定為合適的類型,幫助我們更好的提高導入、查詢等場景的性能,讓業務場景運行的更加高效呢?

我們繼續以發電機組的場景作為示例,創建一張存儲發電機組采樣數據的時序錶:

CREATE TABLE IF NOT EXISTS GENERATOR(
dynamo text TSTag,
manufacturer text TSTag,
model text TSTag,
location text TSTag,
ID bigint TSTag,
voltage numeric TSField,
power bigint TSTag,
frequency numeric TSField,
angle numeric TSField,
time timestamptz TSTime) with (orientation=TIMESERIES, period='7 days', ttl='1 month') distribute by hash(model);

我們可以看到,上述建錶語句中:

  • 對於不隨時間的變化而變化,描述發電機的屬性信息的列(發電機信息、生產廠商、型號、比特置、ID)被設置為tag列,在建錶時需要將對應的列後面指定為TSTag;
  • 對於采樣數據的維度(電壓、功率、頻率、電流相角)這些對應的采樣數值隨時間的變化而變,我們將這些維度設置為field列,建錶語句數據類型後面指定為TSField;
  • 最後一列我們指定為時間列time,存儲field列數據對應的時間信息,建錶時將指定為TSTime。

在寫建錶語句時,對於tag列的順序,我們可以適當優化一下,將唯一性(distinct值)較高的列盡量寫在前面,這樣對於時序場景的性能有一些提昇。如果用戶沒有手動優化,GaussDB(DWS) IoT數倉也可以自適應的幫助用戶提高時序場景的性能,這後面我們會專門文章介紹這一黑科技

另外,創建時序錶時一定要指定錶級參數orientation屬性設置為timeseries。時序錶不需要手動指定DISTRIBUTE BY和PARTITION BY, 默認按照所有tag列分布,且分區健默認為tstim指定的時間列。

對於create table like語法,該語法需要自動從源錶中繼承列名和對應的kv_type類型。因此如果源錶是非時序錶,新錶是時序錶,對應的列的kv_type類型無法確定,則無法創建成功。

時序錶列類型

上面對時序錶的三種kv_type屬性進行了簡單的說明:(維度屬性(TSTag),指標屬性(TSField),時間屬性(TSTime),那麼每個列他們支持的類型(類似建錶語句中的text、int、numeric等)分別都是什麼呢?是否可以不設置kv_type類型?

首先時序錶必須指定一個時間屬性(TSTime),且只能指定一個,且TSTime類型的列不能被删除。至少存在一個TSTagTSField列,否則建錶報錯。

TSTag列支持類型:text, char, bool, int, big int。

TSTime列支持類型:timestamp with time zone, timestamp without time zone。在兼容Oracle語法的數據庫中,也支持date類型。涉及到時區相關操作時,請選擇帶時區的時間類型。

TSField列支持的數據類型同列存錶保持一致

自動設置分區邊界

時序錶具備數據生命周期管理的能力。每天數以億計的數據不間斷湧入,對於很久之前的數據,其價值較低不經常訪問,可以定期將無用的老數據删除。並且由於最新的數據不斷進來,需要定期給錶增加新的分區,避免新數據無法存儲。因此時序錶需要具備定時增加分區和定時删除分區的能力。

時序錶以TSTIME列為分區鍵,創建具有自動分區管理功能的分區錶,幫助我們大大减少運維操作的工作。在上面的建錶語句中,在錶級參數項中可以看到,時序錶指定了自動分區管理兩個參數period和ttl。

  • period:設置自動創建分區的間隔時間,默認值為1 day, 取值範圍:1 hour ~ 100 years。默認會為時序錶創建自增分區任務。自增分區任務動態為我們創建分區,保證當前時刻有足够充裕的分區用於導入數據。
  • ttl:設置自動淘汰分區的時間,取值範圍:1 hour ~ 100 years。默認不創建淘汰分區任務,需要用戶自己在建錶手動指定,或者建錶後通過ALTER TABLE語法設置。淘汰分區的策略是通過計算 nowtime - 分區boundary > ttl,滿足該條件的分區將被drop掉。幫助用戶定時清理過期的舊數據。

上面舉得例子中,時序錶建錶語句沒有指定分區,那麼分區的起始時間是怎麼樣的。為了方便用戶的使用,我們的分區邊界的設置分為了一下幾種情况

  • period設置為“小時” , 分區起始邊界值為下個小時整點,分區的間隔為period的值
  • period設置為“天” , 分區起始邊界值為第二天零點,分區的間隔為period的值
  • period設置為“月” , 分區起始邊界值為下個月零點,分區的間隔為period的值
  • period設置為“年” , 分區起始邊界值為明年零點,分區的間隔為period的值
tsdb=# CREATE TABLE IF NOT EXISTS GENERATOR(
tsdb(# dynamo text TSTag,
tsdb(# manufacturer text TSTag,
tsdb(# model text TSTag,
tsdb(# location text TSTag,
tsdb(# ID bigint TSTag,
tsdb(# voltage numeric TSField,
tsdb(# power bigint TSTag,
tsdb(# frequency numeric TSField,
tsdb(# angle numeric TSField,
tsdb(# time timestamptz TSTime) with (orientation=TIMESERIES, period='1 hour', ttl='1 month') distribute by hash(model);
CREATE TABLE

tsdb=# select now();
              now
-------------------------------
 2022-05-25 15:28:38.520757+08
(1 row)
tsdb=# select relname, boundaries from pg_partition where parentid=(select oid from pg_class where relname='generator') order by boundaries ;
    relname     |         boundaries
----------------+----------------------------
 default_part_1 | {"2022-05-25 16:00:00+08"}
 default_part_2 | {"2022-05-25 17:00:00+08"}
 p1653505200    | {"2022-05-26 03:00:00+08"}
 p1653541200    | {"2022-05-26 13:00:00+08"}
 p1653577200    | {"2022-05-26 23:00:00+08"}
 ......

這樣的使用方式,能够使得用戶能够便捷快速的創建時序錶。當然我們也支持在建錶時用戶手動指定分區邊界的起始值。關於自動分區管理功能更詳細的描述,可以參考《GaussDB(DWS) 分區自動管理介紹》

tsdb=# select now();
              now
-------------------------------
 2022-05-31 20:36:09.700096+08
(1 row)

tsdb=# CREATE TABLE IF NOT EXISTS GENERATOR(
tsdb(# dynamo text TSTag,
tsdb(# manufacturer text TSTag,
tsdb(# model text TSTag,
tsdb(# location text TSTag,
tsdb(# ID bigint TSTag,
tsdb(# voltage numeric TSField,
tsdb(# power bigint TSTag,
tsdb(# frequency numeric TSField,
tsdb(# angle numeric TSField,
tsdb(# time timestamptz TSTime) with (orientation=TIMESERIES, period='1 day') distribute by hash(model)
tsdb-# partition by range(time)
tsdb-# (
tsdb(# PARTITION P1 VALUES LESS THAN('2022-05-30 16:32:45'),
tsdb(# PARTITION P2 VALUES LESS THAN('2022-05-31 16:56:12')
tsdb(# );
WARNING:  partition boundary is less than current time.
CREATE TABLE

tsdb=# select relname, boundaries from pg_partition where parentid=(select oid from pg_class where relname='generator') order by boundaries ;
   relname   |         boundaries
-------------+----------------------------
 p1          | {"2022-05-30 16:32:45+08"}
 p2          | {"2022-05-31 16:56:12+08"}
 p1654073772 | {"2022-06-01 16:56:12+08"}
 p1654160172 | {"2022-06-02 16:56:12+08"}
 ......

至此,我們已經建成了自己的第一張時序錶,接下來我們會針對時序錶的DDL各種操作進行詳細的實踐,幫助大家學好、用好時序數據庫,更好的為用戶的業務服務。

點擊關注,第一時間了解華為雲新鮮技術~

版權聲明
本文為[華為雲開發者聯盟]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/174/202206232135550958.html

隨機推薦