表是存儲和組織數據的基本單位,合理地創建表、設置表索引及屬性,可以為您提供高效的數據處理和分析能力。本文為您介紹在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頁面頂部菜單欄,單擊
。您也可以在元數據管理界面的已登錄實例列表。單擊目標數據庫,鼠標右擊數據庫下已創建的目標模式,選擇新建內部表。
在新建內部表頁面,配置各項參數。
類別
參數
描述
基本屬性
模式
模式名稱。
您可以選擇默認創建的public模式,也可以選擇新建的模式名稱。
表名
新建的Hologres內部表名稱。
描述
新建的Hologres內部表描述。
字段
字段名
表中每一列的標識。
數據類型
字段取值的類型。
主鍵
表中每條數據的唯一標識。
可空
字段是否可以設置為空。
數組
有序的元素序列。
描述
字段的描述信息。
操作
包括刪除、上移和下移。
屬性
存儲模式
包括列存、行存和行列共存三種存儲模式。
默認為列存。
表數據生命周期(秒)
數據第一次寫入的時間開始計算,當到達生命周期后,表數據會在某一段時間內被清除(沒有固定時間段)。
默認生命周期為永久。
Binlog
表是否開啟Binlog,詳情請參見訂閱Hologres Binlog。
Binlog生命周期
Binlog的生命周期,詳情請參見訂閱Hologres Binlog。默認生命周期為永久。
分布列
distribution_key,使用詳情請參見分布鍵Distribution Key。
分段列
event_time_column ,使用詳情請參見Event Time Column(Segment Key)。
聚簇列
clustering_key,使用詳情請參見聚簇索引Clustering Key。
字典編碼列
dictionary_encoding_columns,使用詳情請參見字典編碼Dictionary Encoding。
位圖列
bitmap_columns,使用詳情請參見位圖索引Bitmap。
分區表
無
選擇分區字段。
在頁面右上角,單擊提交。提交之后,您可以在左側對應模式下,刷新出新建的內部表。
其他相關操作:
編輯內部表
在元數據管理界面的已登錄實例列表,雙擊目標內部表。
在目標內部表信息頁,單擊編輯表,可以添加字段、更改表數據周期等部分表屬性。
單擊提交。
刪除內部表
在元數據管理界面的已登錄實例列表,鼠標右擊目標內部表,選擇刪除表。
在刪除表對話框,單擊確認。
表數據預覽
在已登錄實例列表,雙擊目標內部表。
進入表信息頁簽,單擊數據預覽,則可以預覽表數據。
DDL預覽
在目標表信息頁簽,單擊DDL語句,則可以預覽DDL語句。
下一步
創建完表之后,您可以通過數據插入(INSERT 語句)、數據同步和數據遷移實現數據導入,詳情請參見INSERT、數據同步概述和導出。
相關文檔
根據已有表創建新表,您可以選擇復制表結構和表數據,詳情請參見CREATE TABLE AS;也可以選擇復制表結構和表屬性,詳情請參見CREATE TABLE LIKE。
創建分區表請參見CREATE PARTITION TABLE。
創建外部表請參見CREATE FOREIGN TABLE。
修改表屬性請參見ALTER TABLE。