CREATE TABLE
表是存儲和組織數(shù)據(jù)的基本單位,合理地創(chuàng)建表、設(shè)置表索引及屬性,可以為您提供高效的數(shù)據(jù)處理和分析能力。本文為您介紹在Hologres中的建表語法、設(shè)置索引和HoloWeb可視化建表。
建表語法
命令格式
Hologres的建表語法兼容PostgreSQL,通過CREATE TABLE語句創(chuàng)建表,具體語法如下。
說明當前Hologres DDL支持多行事務(wù),V2.0版本起支持多行DML混合事務(wù)。
V2.1版本起支持
create table with property
語法,簡化設(shè)置表屬性方法。
推薦優(yōu)先使用
CREATE TABLE WITH
語法,針對特定場景,如頻繁創(chuàng)建已存在的表(CREATE TABLE IF NOT EXISTS
)并設(shè)置表屬性時,可以顯著提升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;
參數(shù)說明
column_type:為字段的數(shù)據(jù)類型,已支持的數(shù)據(jù)類型可以參見數(shù)據(jù)類型匯總。
set_table_property或
create table with
語法(V2.1版本起支持):為表設(shè)置屬性,詳情請參見設(shè)置表屬性和索引。
合理的建表索引總結(jié)
Hologres是兼容PostgreSQL生態(tài),建表語法與PostgreSQL相同,但是索引與PostgreSQL不同,Hologres支持的索引請參見設(shè)置表屬性和索引。建表時選擇合適的索引,能夠使SQL在執(zhí)行時快速命中數(shù)據(jù),減少IO消耗,以更少的計算資源,實現(xiàn)更快的查詢性能。下圖是一個SQL從發(fā)起到獲取數(shù)據(jù)的執(zhí)行流程,可以通過下圖理解每個索引的作用,以方便實際業(yè)務(wù)中更加方便高效的為表選擇合適的索引。
SQL執(zhí)行時,如果是分區(qū)表,那么會通過分區(qū)裁剪,定位到所在分區(qū)。
通過Distribution Key快速定位到數(shù)據(jù)所在的數(shù)據(jù)分片(Shard)。
通過Event Time Column(原Segment Key)快速定位到數(shù)據(jù)所在的文件。
Clustering Key為數(shù)據(jù)在文件內(nèi)的排序,可以通過Clustering Key快速定位到所在的文件塊。
位圖索引Bitmap是文件內(nèi)的索引,可以通過Bitmap快速定位到符合條件的數(shù)據(jù)所在的行號。
索引適用的場景如下。
索引 | 適用場景 | 示例查詢語句 |
Distribution Key | 適合于頻繁進行Group By的列或者多表Join時的Join字段設(shè)置為Distribution Key,能夠減少數(shù)據(jù)Shuffle,實現(xiàn)Local Join的能力。 |
|
Clustering Key | 將范圍查詢或Filter查詢列作為聚簇索引列。索引過濾具備左匹配原則,建議設(shè)置聚簇索引列不要超過兩列。 |
|
Bitmap | 將等值查詢列作為Bitmap列。 |
|
Event Time Column(原Segment_Key) | 適用于將日志、流量等和時間強相關(guān)的列設(shè)置為Segment_Key。 |
|
設(shè)置表屬性和索引
在Hologres中,可以通過set_table_property
或create table with
命令為表設(shè)置多種屬性,合理的表屬性設(shè)置可以有助于系統(tǒng)高效地組織和查詢數(shù)據(jù)。與數(shù)據(jù)存儲布局有關(guān)的參數(shù)需要和建表語句同時執(zhí)行。
命令格式
-- 2.1版本起支持 create table <table_name> (...) with (property = 'value'[, ...]); -- 所有版本支持 call set_table_property('<table_name>', property, 'value');
說明set_table_property
的調(diào)用需要與create table
在同一事務(wù)中執(zhí)行。Hologres支持的設(shè)置表屬性如下所示,包括但不限于以下幾種表屬性。
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;
參數(shù)說明
具體參數(shù)和相關(guān)內(nèi)容如下表所示:
參數(shù)
說明
列存表
行存表
行列共存表
建議值
建表后是否可修改
orientation
表存儲格式。
column(默認值)
row
row,column
column
否,如需修改請重新建表。
table_group
Table Group。
默認為default table group。
默認為default table group。
默認為default table group。
默認即可。
否,如需修改請重新建表或者Resharding。
distribution_key
分布鍵。
默認為主鍵,根據(jù)業(yè)務(wù)場景修改。
默認為主鍵。
默認為主鍵。
主鍵的子集,建議只選擇一列。
否,如需修改請重新建表。
clustering_key
聚簇索引。
默認為空。
默認為主鍵。
默認為空。
建議最多選擇一列,且僅支持asc序。
否,如需修改請重新建表。
event_time_column
分段鍵。
默認為第一個非空時間戳字段。
不支持。
默認為第一個非空時間戳字段。
建議時間戳字段。
否,如需修改請重新建表。
bitmap_columns
位圖索引。
按需使用。
不支持。
按需使用。
建議用于等值比較的列,一般10列以下。
是,詳情請參見ALTER TABLE。
dictionary_encoding_columns
比特編碼。
按需使用。
不支持。
按需使用。
建議低基數(shù)列,一般10列以下。
是,詳情請參見ALTER TABLE。
time_to_live_in_seconds
表數(shù)據(jù)生命周期。
按需使用。
按需使用。
按需使用。
默認即可,無需設(shè)置。
是,詳情請參見ALTER TABLE。
orientation
指定了數(shù)據(jù)庫表在Hologres中的存儲模式是列存還是行存,從V1.1版本開始支持行列共存的格式,命令語法如下所示。不同的存儲格式適用于不同的查詢場景,建表時默認為列存,其余存儲模式需要建表時顯式指定,詳情請參見表存儲格式:列存、行存、行列共存。
call set_table_property('table_name', 'orientation', '[column | row |row,column]');
table_group
在Hologres中,Shard是指數(shù)據(jù)分片,Table Group是Hologres中特有的邏輯存儲概念,用于管理Shard數(shù),一個Table Group唯一對應(yīng)一組Shard。新建數(shù)據(jù)庫后,如果沒有創(chuàng)建新的Table Group,那么創(chuàng)建第一個表時,會自動建立一個名稱為
<db>_tg_default
的默認Table Group,后續(xù)表創(chuàng)建時沒有指定Table Group將會被指定至默認Table Group中。一般情況下無需設(shè)置Table Group,使用默認Table Group即可,當實例規(guī)格較大(大于256 Core時),建議根據(jù)業(yè)務(wù)情況劃分不同的Table Group和Shard數(shù),帶來更好的性能,使用詳情請參見Table Group與Shard Count操作指南。call set_table_property('table_name', 'table_group', '[tableGroupName]');
distribution_key
設(shè)置分布鍵Distribution Key。Distribution Key指定了表的分布策略,數(shù)據(jù)根據(jù)Distribution Key被分配到各個Shard上,保證Distribution Key相同的記錄會被分配到同一個Shard上。Distribution Key是非常重要的分布式概念,合理的設(shè)置Distribution Key可以提高查詢性能和QPS等,詳情請參見分布鍵Distribution Key。
call set_table_property('table_name', 'distribution_key', '[columnName[,...]]');
clustering_key
設(shè)置聚簇索引Clustering Key,命令語法如下所示。Hologres會根據(jù)Clustering Key在文件內(nèi)對數(shù)據(jù)進行排序,默認為升序(acs)排序。合理地設(shè)置Clustering Key能夠加速在索引列上的Range和Filter查詢,提升查詢性能,詳情請參見聚簇索引Clustering Key。
call set_table_property('table_name', 'clustering_key', '[columnName{:asc} [,...]]');
event_time_column
設(shè)置分段鍵Event_time_column (原Segment Key),命令語法如下所示。文件會根據(jù)Event_time_column劃分,當命中Event_time_column時,可以快速定位到數(shù)據(jù)所在的文件,Event_time_column適用于數(shù)據(jù)為單調(diào)遞增或單調(diào)遞減的有序字段,例如時間戳字段,非常適用于日志、流量等和時間強相關(guān)的數(shù)據(jù),合理設(shè)置可極大提升查詢性能,詳情請參見Event Time Column(Segment Key)。
call set_table_property('table_name', 'event_time_column', '[columnName [,...]]');
bitmap_columns
設(shè)置位圖索引Bitmap,命令語法如下所示。Bitmap能夠快速定位到符合條件數(shù)據(jù)所在的行號,適合將等值查詢條件的數(shù)據(jù)設(shè)置為位圖索引列。默認列存表所有TEXT數(shù)據(jù)類型的字段都會被隱式地設(shè)置為位圖索引列,詳情請參見位圖索引Bitmap。
call set_table_property('table_name', 'bitmap_columns', '[columnName{:[on|off]}[,...]]');
dictionary_encoding_columns
設(shè)置字典編碼Dictionary Encoding,命令語法如下所示。Dictionary Encoding指定列的值構(gòu)建字典映射。字典編碼可以將字符串的比較轉(zhuǎn)成數(shù)字的比較,加速Group By、Filter等查詢。默認列存表所有TEXT數(shù)據(jù)類型的字段都會被設(shè)置為Dictionary Encoding列 ,在Hologres V0.9及之后版本,會根據(jù)數(shù)據(jù)特征自動選擇是否創(chuàng)建字典編碼。
call set_table_property('table_name', 'dictionary_encoding_columns', '[columnName{:[on|off|auto]}[,...]]');
time_to_live_in_seconds(不建議使用)
設(shè)置表的數(shù)據(jù)生命周期(TTL),單位為秒,命令語法如下所示。
TTL過期時間是按照數(shù)據(jù)寫入的時間開始計算,不是按照數(shù)據(jù)更新時間計算。不設(shè)置TTL的時候,默認為100年,Hologres從 V1.3.24版本開始,TTL允許的最小值是一天,即86400秒。TTL的詳細使用說明請參見SQL命令列表。
TTL不是精確的時間,即到期了之后數(shù)據(jù)會在某一段時間(不是固定時間)刪除(只刪除數(shù)據(jù),表還會存在),因此可能會出現(xiàn)PK重復(fù)的問題。生產(chǎn)業(yè)務(wù)不建議使用TTL來管理數(shù)據(jù)的生命周期,建議使用CREATE PARTITION TABLE。
call set_table_property('table_name', 'time_to_live_in_seconds', '<non_negative_literal>');
使用限制
支持將多個字段設(shè)置為Primary Key(即復(fù)合主鍵),被設(shè)置為Primary Key的字段是唯一且非空,同時只能在一個語句里設(shè)置多列為表的Primary Key。Primary Key必須為not nullable的列或者列組合,不支持將Float、Double、Numeric、Array、Json、Date及其他復(fù)雜數(shù)據(jù)類型的字段設(shè)為Primary Key。不支持修改Primary Key,如需修改請重新建表。如下示例指導(dǎo)您將id和ds設(shè)置為表的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
的支持情況如下。參數(shù)
column_constraints
table_constraints
primary key
支持
支持
not null
支持
-
null
支持
-
unique
不支持
不支持
check
不支持
不支持
default
支持
不支持
關(guān)鍵字、保留字、系統(tǒng)字段、特殊字符、大小寫需使用雙引號("")進行轉(zhuǎn)義。
Hologres對列名、表名等關(guān)鍵字的限制包括:列名稱不能以
hg_
開頭,Schema名稱不能以holo_
、hg_或
pg_
開頭。同時還需要遵循PostgreSQL本身的關(guān)鍵字、保留字、系統(tǒng)字段規(guī)范,詳情請參見關(guān)鍵詞列表、系統(tǒng)列列表,這些PostgreSQL關(guān)鍵詞作為列名時需要加雙引號("")進行轉(zhuǎn)義。表名和列名均對大小寫不敏感,如需定義大寫表名、大寫列名、特殊字符表名或列名、以數(shù)字開頭的表名或列名時,可使用雙引號("")進行轉(zhuǎn)義。
如果有自定義字段與系統(tǒng)字段名稱重復(fù),可能會報錯,例如
ctid
。Hologres V2.0版本起優(yōu)化了設(shè)置表屬性時使用雙引號("")進行轉(zhuǎn)義的語法。如果需要對列名進行轉(zhuǎn)義,則需要使用新的語法。如果您仍希望使用舊語法,需要開啟如下GUC。
-- session級別開啟舊語法開關(guān) set hg_disable_parse_holo_property = on; -- DB級別開啟舊語法開關(guān) alter database <db_name> set hg_disable_parse_holo_property = on;
示例如下:
說明在查詢列名稱以數(shù)字開頭的列時,同樣需要使用雙引號("")進行轉(zhuǎn)義,否則會出現(xiàn)列名解析錯誤的情況。
create table "TBL" (a int); select relname from pg_class where relname = 'TBL'; insert into "TBL" values (-1977); select * from "TBL"; ------------------------------------------------------------------ -- Hologres V2.0版本起,為需要轉(zhuǎn)義的列設(shè)置表屬性的語法 begin; create table tbl (c1 int not null); call set_table_property('tbl', 'clustering_key', '"c1":asc'); commit; -- Hologres V2.0版本前,為需要轉(zhuǎn)義的列設(shè)置表屬性的語法 begin; create table tbl (c1 int not null); call set_table_property('tbl', 'clustering_key', '"c1:asc"'); commit; ------------------------------------------------------------------ -- Hologres V2.1版本起,為多列(包含大寫)設(shè)置表屬性的語法 begin; create table tbl ("C1" int not null, c2 text not null) with (clustering_key = '"C1",c2'); commit; -- Hologres V2.0版本起,為多列(包含大寫)設(shè)置表屬性的語法 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版本前,為多列(包含大寫)設(shè)置表屬性的語法 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;
在創(chuàng)建表時,如果不存在同名表且語義正確,表創(chuàng)建都會返回成功。如果不指定
IF NOT EXISTS
選項而存在同名表,則返回異常。如果指定IF NOT EXISTS
選項,Hologres會提示信息,跳過表創(chuàng)建步驟,返回成功,直觀的規(guī)則如下。配置項
指定if not exists
不指定if not exists
存在同名表
NOTICE:relation “xx“already exists,skippingSUCCEED
ERROR:relation is already exists.
不存在同名表
SUCCEED
SUCCEED
表名稱的長度不能超過64字節(jié),超過64字節(jié)將被截斷。
暫時不支持修改數(shù)據(jù)類型,如需修改,請重新建表。
行存表必須設(shè)置主鍵,行列共存表必須設(shè)置主鍵,列存表主鍵可選。
不支持調(diào)整列順序,如需調(diào)整,請重新建表。
orientation、distribution_key、clustering_key、event_time_column屬性決定了數(shù)據(jù)寫入后的存儲布局,因此建表后不支持更改,如需修改,需要重新建表;bitmap和dictionary屬性不影響數(shù)據(jù)存儲布局,可以在建表后按需更改。
不支持將已有表的非空(
not null
)字段改成空(nullable
)字段,同時不支持將nullable
的字段改為not null
的字段,如需更改請重新建表。
查看表結(jié)構(gòu)
您可以執(zhí)行如下命令查看TABLE的具體DDL:
create extension hg_toolkit; --該命令是DB級別,一個DB執(zhí)行一次即可
select hg_dump_script('[<schema_name>.]<table_name>');
您也可以通過HoloWeb,在元數(shù)據(jù)管理模塊進行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;
新建分區(qū)表并指定Primary Key。
說明分區(qū)表有主鍵時,主鍵里面必須包含分區(qū)字段。
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;
分區(qū)表還需要創(chuàng)建分區(qū)子表,詳情請參見CREATE PARTITION TABLE。
新建普通表并設(shè)置默認值。
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可視化新建內(nèi)部表
HoloWeb提供可視化一鍵建表功能,無需寫SQL命令就能創(chuàng)建表,步驟如下。
進入HoloWeb頁面,詳情請參見連接HoloWeb并執(zhí)行查詢。
在HoloWeb頁面頂部菜單欄,單擊
。您也可以在元數(shù)據(jù)管理界面的已登錄實例列表。單擊目標數(shù)據(jù)庫,鼠標右擊數(shù)據(jù)庫下已創(chuàng)建的目標模式,選擇新建內(nèi)部表。
在新建內(nèi)部表頁面,配置各項參數(shù)。
類別
參數(shù)
描述
基本屬性
模式
模式名稱。
您可以選擇默認創(chuàng)建的public模式,也可以選擇新建的模式名稱。
表名
新建的Hologres內(nèi)部表名稱。
描述
新建的Hologres內(nèi)部表描述。
字段
字段名
表中每一列的標識。
數(shù)據(jù)類型
字段取值的類型。
主鍵
表中每條數(shù)據(jù)的唯一標識。
可空
字段是否可以設(shè)置為空。
數(shù)組
有序的元素序列。
描述
字段的描述信息。
操作
包括刪除、上移和下移。
屬性
存儲模式
包括列存、行存和行列共存三種存儲模式。
默認為列存。
表數(shù)據(jù)生命周期(秒)
數(shù)據(jù)第一次寫入的時間開始計算,當?shù)竭_生命周期后,表數(shù)據(jù)會在某一段時間內(nèi)被清除(沒有固定時間段)。
默認生命周期為永久。
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。
分區(qū)表
無
選擇分區(qū)字段。
在頁面右上角,單擊提交。提交之后,您可以在左側(cè)對應(yīng)模式下,刷新出新建的內(nèi)部表。
其他相關(guān)操作:
編輯內(nèi)部表
在元數(shù)據(jù)管理界面的已登錄實例列表,雙擊目標內(nèi)部表。
在目標內(nèi)部表信息頁,單擊編輯表,可以添加字段、更改表數(shù)據(jù)周期等部分表屬性。
單擊提交。
刪除內(nèi)部表
在元數(shù)據(jù)管理界面的已登錄實例列表,鼠標右擊目標內(nèi)部表,選擇刪除表。
在刪除表對話框,單擊確認。
表數(shù)據(jù)預(yù)覽
在已登錄實例列表,雙擊目標內(nèi)部表。
進入表信息頁簽,單擊數(shù)據(jù)預(yù)覽,則可以預(yù)覽表數(shù)據(jù)。
DDL預(yù)覽
在目標表信息頁簽,單擊DDL語句,則可以預(yù)覽DDL語句。
下一步
創(chuàng)建完表之后,您可以通過數(shù)據(jù)插入(INSERT 語句)、數(shù)據(jù)同步和數(shù)據(jù)遷移實現(xiàn)數(shù)據(jù)導(dǎo)入,詳情請參見INSERT、數(shù)據(jù)同步概述和導(dǎo)出。
相關(guān)文檔
根據(jù)已有表創(chuàng)建新表,您可以選擇復(fù)制表結(jié)構(gòu)和表數(shù)據(jù),詳情請參見CREATE TABLE AS;也可以選擇復(fù)制表結(jié)構(gòu)和表屬性,詳情請參見CREATE TABLE LIKE。
創(chuàng)建分區(qū)表請參見CREATE PARTITION TABLE。
創(chuàng)建外部表請參見CREATE FOREIGN TABLE。
修改表屬性請參見ALTER TABLE。