表是儲存和組織資料的基本單位,合理地建立表、設定表索引及屬性,可以為您提供高效的資料處理和分析能力。本文為您介紹在Hologres中的建表文法、設定索引和HoloWeb可視化建表。
建表文法
命令格式
Hologres的建表文法相容PostgreSQL,通過CREATE TABLE語句建立表,具體文法如下。
推薦優先使用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的能力。 | select * from tbl1 join tbl2 on tbl1.a=tbl2.c;
|
Clustering Key | 將範圍查詢或Filter查詢列作為聚簇索引列。索引過濾具備左匹配原則,建議設定聚簇索引列不要超過兩列。 | select sum(a) from tb1 where a > 100 and a < 200;
|
Bitmap | 將等值查詢列作為Bitmap列。 | select * from tb1 where a =100;
|
Event Time Column(原Segment_Key) | 適用於將日誌、流量等和時間強相關的列設定為Segment_Key。 | select sum(a) from tb1 where ts > '2020-01-01' and a < '2020-03-02';
|
設定表屬性和索引
在Hologres中,可以通過set_table_property
或create table with
命令為表設定多種屬性,合理的表屬性設定可以有助於系統高效地組織和查詢資料。與資料存放區布局有關的參數需要和建表語句同時執行。
命令格式
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。 |
使用限制
支援將多個欄位設定為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 |
參數 | 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。
set hg_disable_parse_holo_property = on;
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";
begin;
create table tbl (c1 int not null);
call set_table_property('tbl', 'clustering_key', '"c1":asc');
commit;
begin;
create table tbl (c1 int not null);
call set_table_property('tbl', 'clustering_key', '"c1:asc"');
commit;
begin;
create table tbl ("C1" int not null, c2 text not null) with (clustering_key = '"C1",c2');
commit;
begin;
create table tbl ("C1" int not null, c2 text not null);
call set_table_property('tbl', 'clustering_key', '"C1",c2');
commit;
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 |
配置項 | 指定if not exists | 不指定if not exists |
存在同名表 | NOTICE:relation “xx“already exists,skippingSUCCEED
| ERROR:relation is already exists.
|
不存在同名表 | SUCCEED
| SUCCEED
|
表名稱的長度不能超過127位元組,超過127位元組將被截斷。
暫時不支援修改資料類型,如需修改,請重建立表。
行存表必須設定主鍵,行列共存表必須設定主鍵,列存表主鍵可選。
不支援調整列順序,如需調整,請重建立表。
orientation、distribution_key、clustering_key、event_time_column屬性決定了資料寫入後的儲存布局,因此建表後不支援更改,如需修改,需要重建立表;bitmap和dictionary屬性不影響資料存放區布局,可以在建表後按需更改。
不支援將已有表的非空(not null
)欄位改成空(nullable
)欄位,同時不支援將nullable
的欄位改為not null
的欄位,如需更改請重建立表。
查看錶結構
您可以執行如下命令查看TABLE的具體DDL:
create extension hg_toolkit;
select hg_dump_script('[<schema_name>.]<table_name>');
HoloWeb可視化建立內部表
HoloWeb提供可視化一鍵建表功能,無需寫SQL命令就能建立表,步驟如下。
進入HoloWeb頁面,詳情請參見串連HoloWeb並執行查詢。
在HoloWeb頁面頂部功能表列,單擊。
您也可以在中繼資料管理介面的已登入執行個體列表。單擊目標資料庫,滑鼠右擊資料庫下已建立的目標模式,選擇建立內部表。
在頁面右上方,單擊提交。提交之後,您可以在左側對應模式下,重新整理出建立的內部表。
其他相關操作:
編輯內部表
在中繼資料管理介面的已登入執行個體列表,雙擊目標內部表。
在目標內部表資訊頁,單擊編輯表,可以添加欄位、更改表資料周期等部分表屬性。
單擊提交。
刪除內部表
在中繼資料管理介面的已登入執行個體列表,滑鼠右擊目標內部表,選擇刪除表。
在刪除表對話方塊,單擊確認。
表資料預覽
在已登入執行個體列表,雙擊目標內部表。
進入表資訊頁簽,單擊資料預覽,則可以預覽表資料。
DDL預覽
在目標表資訊頁簽,單擊DDL語句,則可以預覽DDL語句。