表是儲存和組織資料的基本單位,合理地建立表、設定表索引及屬性,可以為您提供高效的資料處理和分析能力。本文為您介紹在Hologres中的建表文法、設定索引和HoloWeb可視化建表。
建表文法
命令格式
Hologres的建表文法相容PostgreSQL,通過CREATE TABLE語句建立表,具體文法如下。
說明當前Hologres DDL支援多行事務,V2.0版本起支援多行DML混合事務。
V2.1版本起支援
create table with property
文法,簡化設定表屬性方法。
推薦優先使用
CREATE TABLE WITH
文法,針對特定情境,如頻繁建立已存在的表(CREATE TABLE IF NOT EXISTS
)並設定表屬性時,可以顯著提升DDL效能。V2.1版本起支援的文法:
BEGIN; CREATE TABLE [ IF NOT EXISTS] [schema_name.] table_name ([ { column_name column_type [column_constraints, [...]] | table_constraints [,...] } ]) [WITH ( property = 'value', [, ...] )] ; COMMENT ON COLUMN < tablename.column > IS 'value'; COMMENT ON TABLE < tablename > IS 'value'; COMMIT;
所有版本都支援的文法:
begin; create table [if not exists] [schema_name.]table_name ([ { column_name column_type [column_constraints, [...]] | table_constraints [, ...] } ]); call set_table_property('<table_name>', property, value); comment on column <tablename.column> is 'value'; comment on table <tablename> is 'value'; commit;
合理的建表索引總結
Hologres是相容PostgreSQL生態,建表文法與PostgreSQL相同,但是索引與PostgreSQL不同,Hologres支援的索引請參見設定表屬性和索引。建表時選擇合適的索引,能夠使SQL在執行時快速命中資料,減少IO消耗,以更少的計算資源,實現更快的查詢效能。下圖是一個SQL從發起到擷取資料的執行流程,可以通過下圖理解每個索引的作用,以方便實際業務中更加方便高效的為表選擇合適的索引。
SQL執行時,如果是分區表,那麼會通過分區裁剪,定位到所在分區。
通過Distribution Key快速定位到資料所在的資料分區(Shard)。
通過Event Time Column(原Segment Key)快速定位到資料所在的檔案。
Clustering Key為資料在檔案內的排序,可以通過Clustering Key快速定位到所在的檔案塊。
位元影像索引Bitmap是檔案內的索引,可以通過Bitmap快速定位到合格資料所在的行號。
索引適用的情境如下。
索引 | 適用情境 | 樣本查詢語句 |
Distribution Key | 適合於頻繁進行Group By的列或者多表Join時的Join欄位設定為Distribution Key,能夠減少資料Shuffle,實現Local Join的能力。 |
|
Clustering Key | 將範圍查詢或Filter查詢列作為聚簇索引列。索引過濾具備左匹配原則,建議設定聚簇索引列不要超過兩列。 |
|
Bitmap | 將等值查詢列作為Bitmap列。 |
|
Event Time Column(原Segment_Key) | 適用於將日誌、流量等和時間強相關的列設定為Segment_Key。 |
|
設定表屬性和索引
在Hologres中,可以通過set_table_property
或create table with
命令為表設定多種屬性,合理的表屬性設定可以有助於系統高效地組織和查詢資料。與資料存放區布局有關的參數需要和建表語句同時執行。
命令格式
-- 2.1版本起支援 create table <table_name> (...) with (property = 'value'[, ...]); -- 所有版本支援 call set_table_property('<table_name>', property, 'value');
說明set_table_property
的調用需要與create table
在同一事務中執行。Hologres支援的設定表屬性如下所示,包括但不限於以下幾種表屬性。
V2.1版本起支援的文法:
CREATE TABLE <table_name> (...) WITH ( orientation = '[column | row | row,column]', table_group = '[tableGroupName]', distribution_key = 'columnName[,...]]', clustering_key = '[columnName{:asc]} [,...]]', event_time_column = '[columnName [,...]]', bitmap_columns = '[columnName [,...]]', dictionary_encoding_columns = '[columnName [,...]]', time_to_live_in_seconds = '<non_negative_literal>' [,storage_mode, ...] );
所有版本都支援的文法:
BEGIN; CREATE TABLE <table_name> (...); call set_table_property('table_name', 'orientation', '[column | row]'); call set_table_property('table_name', 'table_group', '[tableGroupName]'); call set_table_property('table_name', 'distribution_key', '[columnName[,...]]'); call set_table_property('table_name', 'clustering_key', '[columnName{:asc]} [,...]]'); call set_table_property('table_name', 'event_time_column', '[columnName [,...]]'); call set_table_property('table_name', 'bitmap_columns', '[columnName [,...]]'); call set_table_property('table_name', 'dictionary_encoding_columns', '[columnName [,...]]'); call set_table_property('table_name', 'time_to_live_in_seconds', '<non_negative_literal>'); COMMIT;
參數說明
具體參數和相關內容如下表所示:
參數
說明
列存表
行存表
行列共存表
建議值
建表後是否可修改
orientation
表格儲存體格式。
column(預設值)
row
row,column
column
否,如需修改請重建立表。
table_group
Table Group。
預設為default table group。
預設為default table group。
預設為default table group。
預設即可。
否,如需修改請重建立表或者Resharding。
distribution_key
分布鍵。
預設為主鍵,根據業務情境修改。
預設為主鍵。
預設為主鍵。
主鍵的子集,建議只選擇一列。
否,如需修改請重建立表。
clustering_key
聚簇索引。
預設為空白。
預設為主鍵。
預設為空白。
建議最多選擇一列,且僅支援asc序。
否,如需修改請重建立表。
event_time_column
分段鍵。
預設為第一個非空時間戳記欄位。
不支援。
預設為第一個非空時間戳記欄位。
建議時間戳記欄位。
否,如需修改請重建立表。
bitmap_columns
位元影像索引。
按需使用。
不支援。
按需使用。
建議用於等值比較的列,一般10列以下。
是,詳情請參見ALTER TABLE。
dictionary_encoding_columns
位元編碼。
按需使用。
不支援。
按需使用。
建議低基數列,一般10列以下。
是,詳情請參見ALTER TABLE。
time_to_live_in_seconds
表資料生命週期。
按需使用。
按需使用。
按需使用。
預設即可,無需設定。
是,詳情請參見ALTER TABLE。
orientation
指定了資料庫表在Hologres中的儲存模式是列存還是行存,從V1.1版本開始支援行列共存的格式,命令文法如下所示。不同的儲存格式適用於不同的查詢情境,建表時預設為列存,其餘儲存模式需要建表時顯式指定,詳情請參見表格儲存體格式:列存、行存、行列共存。
call set_table_property('table_name', 'orientation', '[column | row |row,column]');
table_group
在Hologres中,Shard是指資料分區,Table Group是Hologres中特有的邏輯儲存概念,用於管理Shard數,一個Table Group唯一對應一組Shard。建立資料庫後,如果沒有建立新的Table Group,那麼建立第一個表時,會自動建立一個名稱為
<db>_tg_default
的預設Table Group,後續表建立時沒有指定Table Group將會被指定至預設Table Group中。一般情況下無需設定Table Group,使用預設Table Group即可,當執行個體規格較大(大於256 Core時),建議根據業務情況劃分不同的Table Group和Shard數,帶來更好的效能,使用詳情請參見Table Group與Shard Count操作指南。call set_table_property('table_name', 'table_group', '[tableGroupName]');
distribution_key
設定分布鍵Distribution Key。Distribution Key指定了表的分布策略,資料根據Distribution Key被分配到各個Shard上,保證Distribution Key相同的記錄會被分配到同一個Shard上。Distribution Key是非常重要的分布式概念,合理的設定Distribution Key可以提高查詢效能和QPS等,詳情請參見分布鍵Distribution Key。
call set_table_property('table_name', 'distribution_key', '[columnName[,...]]');
clustering_key
設定聚簇索引Clustering Key,命令文法如下所示。Hologres會根據Clustering Key在檔案內對資料進行排序,預設為升序(acs)排序。合理地設定Clustering Key能夠加速在索引列上的Range和Filter查詢,提升查詢效能,詳情請參見聚簇索引Clustering Key。
call set_table_property('table_name', 'clustering_key', '[columnName{:asc} [,...]]');
event_time_column
設定分段鍵Event_time_column (原Segment Key),命令文法如下所示。檔案會根據Event_time_column劃分,當命中Event_time_column時,可以快速定位到資料所在的檔案,Event_time_column適用於資料為單調遞增或單調遞減的有序欄位,例如時間戳記欄位,非常適用於日誌、流量等和時間強相關的資料,合理設定可極大提升查詢效能,詳情請參見Event Time Column(Segment Key)。
call set_table_property('table_name', 'event_time_column', '[columnName [,...]]');
bitmap_columns
設定位元影像索引Bitmap,命令文法如下所示。Bitmap能夠快速定位到符合條件資料所在的行號,適合將等值查詢條件的資料設定為位元影像索引列。預設列存表所有TEXT資料類型的欄位都會被隱式地設定為位元影像索引列,詳情請參見位元影像索引Bitmap。
call set_table_property('table_name', 'bitmap_columns', '[columnName{:[on|off]}[,...]]');
dictionary_encoding_columns
設定字典編碼Dictionary Encoding,命令文法如下所示。Dictionary Encoding指定列的值構建字典映射。字典編碼可以將字串的比較轉成數位比較,加速Group By、Filter等查詢。預設列存表所有TEXT資料類型的欄位都會被設定為Dictionary Encoding列 ,在Hologres V0.9及之後版本,會根據資料特徵自動選擇是否建立字典編碼。
call set_table_property('table_name', 'dictionary_encoding_columns', '[columnName{:[on|off|auto]}[,...]]');
time_to_live_in_seconds(不建議使用)
設定表的資料生命週期(TTL),單位為秒,命令文法如下所示。
TTL到期時間是按照資料寫入的時間開始計算,不是按照資料更新時間計算。不設定TTL的時候,預設為100年,Hologres從 V1.3.24版本開始,TTL允許的最小值是一天,即86400秒。TTL的詳細使用說明請參見SQL命令列表。
TTL不是精確的時間,即到期了之後資料會在某一段時間(不是固定時間)刪除(只刪除資料,表還會存在),因此可能會出現PK重複的問題。生產業務不建議使用TTL來管理資料的生命週期,建議使用CREATE PARTITION TABLE。
call set_table_property('table_name', 'time_to_live_in_seconds', '<non_negative_literal>');
使用限制
支援將多個欄位設定為Primary Key(即複合主鍵),被設定為Primary Key的欄位是唯一且非空,同時只能在一個語句裡設定多列為表的Primary Key。Primary Key必須為not nullable的列或者列組合,不支援將Float、Double、Numeric、Array、Json、Date及其他複雜資料類型的欄位設為Primary Key。不支援修改Primary Key,如需修改請重建立表。如下樣本指導您將id和ds設定為表的Primary Key。
BEGIN; CREATE TABLE public.test ( "id" text NOT NULL, "ds" text NOT NULL, PRIMARY KEY (id,ds) ); CALL SET_TABLE_PROPERTY('public.test', 'orientation', 'column'); COMMIT;
列約束
column_constraints
和資料表條件約束table_constraints
的支援情況如下。參數
column_constraints
table_constraints
primary key
支援
支援
not null
支援
-
null
支援
-
unique
不支援
不支援
check
不支援
不支援
default
支援
不支援
關鍵字、保留字、系統欄位、特殊字元、大小寫需使用雙引號("")進行轉義。
Hologres對列名、表名等關鍵字的限制包括:列名稱不能以
hg_
開頭、Schema名稱不能以holo_
、hg_
pg_
開頭。同時還需要遵循PostgreSQL本身的關鍵字、保留字、系統欄位規範,詳情請參見關鍵詞列表、系統列列表,這些PostgreSQL關鍵詞作為列名時需要加雙引號("")進行轉義。表名和列名均對大小寫不敏感,如需定義大寫表名、大寫列名、特殊字元表名或列名、以數字開頭的表名或列名時,可使用雙引號("")進行轉義。
如果有自訂欄位與系統欄位名稱重複,可能會報錯,例如
ctid
。Hologres V2.0版本起最佳化了設定表屬性時使用雙引號("")進行轉義的文法。如果需要對列名進行轉義,則需要使用新的文法。如果您仍希望使用舊文法,需要開啟如下GUC。
-- session層級開啟舊文法開關 set hg_disable_parse_holo_property = on; -- DB層級開啟舊文法開關 alter database <db_name> set hg_disable_parse_holo_property = on;
樣本如下:
說明在查詢列名稱以數字開頭的列時,同樣需要使用雙引號("")進行轉義,否則會出現列名解析錯誤的情況。
create table "TBL" (a int); select relname from pg_class where relname = 'TBL'; insert into "TBL" values (-1977); select * from "TBL"; ------------------------------------------------------------------ -- Hologres V2.0版本起,為需要轉義的列設定表屬性的文法 begin; create table tbl (c1 int not null); call set_table_property('tbl', 'clustering_key', '"c1":asc'); commit; -- Hologres V2.0版本前,為需要轉義的列設定表屬性的文法 begin; create table tbl (c1 int not null); call set_table_property('tbl', 'clustering_key', '"c1:asc"'); commit; ------------------------------------------------------------------ -- Hologres V2.1版本起,為多列(包含大寫)設定表屬性的文法 begin; create table tbl ("C1" int not null, c2 text not null) with (clustering_key = '"C1",c2'); commit; -- Hologres V2.0版本起,為多列(包含大寫)設定表屬性的文法 begin; create table tbl ("C1" int not null, c2 text not null); call set_table_property('tbl', 'clustering_key', '"C1",c2'); commit; -- Hologres V2.0版本前,為多列(包含大寫)設定表屬性的文法 begin; create table tbl ("C1" int not null, c2 text not null); call set_table_property('tbl', 'clustering_key', '"C1,c2"'); commit; ------------------------------------------------------------------ create table "Tab_$A%*" (a int); select relname from pg_class where relname = 'Tab_$A%*'; insert into "Tab_$A%*" values (-1977); select * from "Tab_$A%*"; ------------------------------------------------------------------ create table tbl ("2c" int not null); insert into tbl values (3), (4); select "2c" from tbl;
在建立表時,如果不存在同名表且語義正確,表建立都會返回成功。如果不指定
IF NOT EXISTS
選項而存在同名表,則返回異常。如果指定IF NOT EXISTS
選項,Hologres會提示資訊,跳過表建立步驟,返回成功,直觀的規則如下。配置項
指定if not exists
不指定if not exists
存在同名表
NOTICE:relation “xx“already exists,skippingSUCCEED
ERROR:relation is already exists.
不存在同名表
SUCCEED
SUCCEED
表名稱的長度不能超過64位元組,超過64位元組將被截斷。
暫時不支援修改資料類型,如需修改,請重建立表。
行存表必須設定主鍵,行列共存表必須設定主鍵,列存表主鍵可選。
不支援調整列順序,如需調整,請重建立表。
orientation、distribution_key、clustering_key、event_time_column屬性決定了資料寫入後的儲存布局,因此建表後不支援更改,如需修改,需要重建立表;bitmap和dictionary屬性不影響資料存放區布局,可以在建表後按需更改。
不支援將已有表的非空(
not null
)欄位改成空(nullable
)欄位,同時不支援將nullable
的欄位改為not null
的欄位,如需更改請重建立表。
查看錶結構
您可以執行如下命令查看TABLE的具體DDL:
create extension hg_toolkit; --該命令是DB層級,一個DB執行一次即可
select hg_dump_script('[<schema_name>.]<table_name>');
您也可以通過HoloWeb,在中繼資料管理模組進行DDL查看。
為提升建表的便捷性和可閱讀性,從Hologres V2.2版本開始,
hg_dump_script
返回的表屬性從原CALL文法更改為WITH文法。
使用樣本
建立普通列存表並指定Primary Key。
說明Distribution Key必須是Primary Key的子集。
begin; CREATE TABLE tbl ( "id" bigint NOT NULL, "name" text NOT NULL, "age" bigint, "class" text NOT NULL, "reg_timestamp" timestamptz NOT NULL, PRIMARY KEY (id,age) ); call set_table_property('tbl', 'orientation', 'column'); call set_table_property('tbl', 'distribution_key', 'id'); call set_table_property('tbl', 'clustering_key', 'age'); call set_table_property('tbl', 'event_time_column', 'reg_timestamp'); call set_table_property('tbl', 'bitmap_columns', 'name,class'); call set_table_property('tbl', 'dictionary_encoding_columns', 'class:auto'); commit;
建立分區表並指定Primary Key。
說明分區表有主鍵時,主鍵裡面必須包含分區欄位。
begin; CREATE TABLE www ( name text NOT NULL, ds text NOT NULL, age text NOT NULL, PRIMARY KEY (name,ds) ) PARTITION BY LIST(ds); CALL SET_TABLE_PROPERTY('www', 'orientation', 'column'); commit;
分區表還需要建立分區子表,詳情請參見CREATE PARTITION TABLE。
建立普通表並設定預設值。
begin; CREATE TABLE tbl_default ( smallint_col smallint DEFAULT 0, int_col int DEFAULT 0, bigint_col bigint DEFAULT 0, boolean_col boolean DEFAULT FALSE, float_col real DEFAULT 0.0, double_col double precision DEFAULT 0.0, decimal_col decimal(2, 1) DEFAULT 0.0, text_col text DEFAULT 'N', char_col char(2) DEFAULT 'N', varchar_col varchar(200) DEFAULT 'N', timestamptz_col timestamptz DEFAULT now(), date_col date DEFAULT now(), timestamp_col timestamp DEFAULT now() ); commit;
HoloWeb可視化建立內部表
HoloWeb提供可視化一鍵建表功能,無需寫SQL命令就能建立表,步驟如下。
進入HoloWeb頁面,詳情請參見串連HoloWeb。
在HoloWeb頁面頂部功能表列,單擊
。您也可以在中繼資料管理介面的已登入執行個體列表。單擊目標資料庫,滑鼠右擊資料庫下已建立的目標模式,選擇建立內部表。
在建立內部表頁面,配置各項參數。
在頁面右上方,單擊提交。提交之後,您可以在左側對應模式下,重新整理出建立的內部表。
其他相關操作:
編輯內部表
在中繼資料管理介面的已登入執行個體列表,雙擊目標內部表。
在目標內部表資訊頁,單擊編輯表,可以添加欄位、更改表資料周期等部分表屬性。
單擊提交。
刪除內部表
在中繼資料管理介面的已登入執行個體列表,滑鼠右擊目標內部表,選擇刪除表。
在刪除表對話方塊,單擊確認。
表資料預覽
在已登入執行個體列表,雙擊目標內部表。
進入表資訊頁簽,單擊資料預覽,則可以預覽表資料。
DDL預覽
在目標表資訊頁簽,單擊DDL語句,則可以預覽DDL語句。
下一步
建立完表之後,您可以通過資料插入(INSERT 語句)、資料同步和資料移轉實現資料匯入,詳情請參見INSERT、資料同步概述和資料移轉。
相關文檔
根據已有表建立新表,您可以選擇複製表結構和表資料,詳情請參見CREATE TABLE AS;也可以選擇複製表結構和表屬性,詳情請參見CREATE TABLE LIKE。
建立分區表請參見CREATE PARTITION TABLE。
建立外部表格請參見CREATE FOREIGN TABLE。
修改表屬性請參見ALTER TABLE。