為了確保數據表中每一條記錄的唯一性、數據的一致性和方便數據管理,您需要為表設置主關鍵字(Primary Key,簡稱主鍵或PK)。Hologres中主鍵與傳統數據庫主鍵特性一致,是表中記錄的唯一標識,代表了表數據的唯一性。因此被設置為主鍵的字段是唯一的且是非空的,并且支持設置多個字段為主鍵。本文為您介紹在Hologres中為表設置主鍵。
主鍵介紹
在Hologres中,系統會自動在底層保存一個主鍵索引文件,采用行存結構存儲,提供高速的KV(key- value)服務,索引文件的Key為表的主鍵PK,Value為RID(Row Identified,原名為unique_id)和聚簇索引(Clustering Key)。RID每次UPSERT自動生成,單調遞增。主鍵索引文件能夠實現高效的主鍵沖突判定并輔助數據文件定位。假如為表設置了PK,那么就可以通過PK在主鍵索引文件中快速定位到RID和Clustering Key,再通過RID和Clustering Key定位到數據所在的文件。
因此在Hologres中設置了主鍵,可以非常方便地支持實時數倉場景下的多種訴求:
支持高性能的UPSERT或DELETE。
Hologres具有傳統數據庫高性能Append Only類型的寫入特性外,還可以通過主鍵實現高性能的整行寫入更新、部分列寫入更新。在進行寫入更新時只需要根據主鍵更新,不需要全表掃描,從而達到高性能的UPSERT,同時也能保證數據的唯一性。寫入更新的詳細技術原理請參見Hologres寫入技術揭秘。
支持高QPS的基于主鍵查詢。
在表存儲格式:列存、行存、行列共存一文中介紹:如果為表設置了PK,在基于PK的查詢場景中,就能快速根據主鍵定位到整行數據,提升查詢性能。尤其是當表設置為行存表時,主鍵默認為Clustering Key和Distribution Key,就能通過主鍵定位到數據文件,實現超高QPS的主鍵點查,且延遲在毫秒級,適用于實時風控、實時推薦等在線應用場景,詳細原理請參見Hologres在線服務能力技術揭秘。
使用建議
主鍵的設置盡量選擇含有實際業務意義的字段,不建議將Serial類型的字段設置為主鍵,因為Serial類型在寫入的時候是表鎖,導致寫入性能有損失,且隨著數據的增長,長度容易溢出。
使用限制
使用示例
以下為Hologres V2.1版本起的語法示例。如果您的實例為V2.0及以前版本,需要將DDL中的WITH (property = 'value')
語句改為CALL set_table_property
語句,詳情請參見CREATE TABLE。
新建普通列存表并指定一個主鍵。
V2.1版本起支持的建表語法:
CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id) ) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'age', event_time_column = 'reg_timestamp', bitmap_columns = 'name,class', dictionary_encoding_columns = 'class:auto' );
所有版本支持的建表語法:
BEGIN; CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint, class text, reg_timestamp timesatmptz, PRIMARY KEY (id) ); CALL set_table_property('tbl_1', 'orientation', 'column'); CALL set_table_property('tbl_1', 'distribution_key', 'id'); CALL set_table_property('tbl_1', 'clustering_key', 'age'); CALL set_table_property('tbl_1', 'event_time_column', 'reg_timestamp'); CALL set_table_property('tbl_1', 'bitmap_columns', 'name,class'); CALL set_table_property('tbl_1', 'dictionary_encoding_columns', 'class:auto'); COMMIT;
新建一個普通列存表并指定兩個主鍵。
V2.1版本起支持的建表語法:
CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text NOT NULL, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id,age) ) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'age', event_time_column = 'reg_timestamp', bitmap_columns = 'name,class', dictionary_encoding_columns = 'class:auto' );
所有版本支持的建表語法:
BEGIN; CREATE TABLE tbl_2 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text NOT NULL, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id,age) ); CALL set_table_property('tbl_2', 'orientation', 'column'); CALL set_table_property('tbl_2', 'distribution_key', 'id'); CALL set_table_property('tbl_2', 'clustering_key', 'age'); CALL set_table_property('tbl_2', 'event_time_column', 'reg_timestamp'); CALL set_table_property('tbl_2', 'bitmap_columns', 'name,class'); CALL set_table_property('tbl_2', 'dictionary_encoding_columns', 'class:auto'); COMMIT;
創建行存表并指定主鍵。
V2.1版本起支持的建表語法:
CREATE TABLE public.tbl_row ( id text NOT NULL, name text NOT NULL, class text, PRIMARY KEY (id) ) WITH ( orientation = 'row', distribution_key = 'id', clustering_key = 'id' );
所有版本支持的建表語法:
BEGIN; CREATE TABLE public.tbl_row ( id text NOT NULL, name text NOT NULL, class text , PRIMARY KEY (id) ); CALL set_table_property('public.tbl_row', 'orientation', 'row'); CALL set_table_property('public.tbl_row', 'clustering_key', 'id'); CALL set_table_property('public.tbl_row', 'distribution_key', 'id'); COMMIT;
創建分區表并指定主鍵。
V2.1版本起支持的建表語法:
BEGIN; CREATE TABLE public.tbl_parent( a text , b int, c timestamp, d text, ds text, PRIMARY KEY (ds,b) ) PARTITION BY LIST(ds) WITH ( orientation = 'column'); CREATE TABLE public.tbl_child_1 PARTITION OF public.tbl_parent FOR VALUES IN('20221207'); CREATE TABLE public.tbl_child_2 PARTITION OF public.tbl_parent FOR VALUES IN('20221208'); COMMIT;
所有版本支持的建表語法:
BEGIN; CREATE TABLE public.tbl_parent( a text , b int, c timestamp, d text, ds text, PRIMARY KEY (ds,b) ) PARTITION BY LIST(ds); CALL set_table_property('public.tbl_parent', 'orientation', 'column'); CREATE TABLE public.tbl_child_1 PARTITION OF public.tbl_parent FOR VALUES IN('20221207'); CREATE TABLE public.tbl_child_2 PARTITION OF public.tbl_parent FOR VALUES IN('20221208'); COMMIT;
相關文檔
根據業務查詢場景設置合適的表屬性指南,請參見場景化建表調優指南。
Key/Value查詢場景建表和查詢最佳實踐,請參見Key/Value查詢場景最佳實踐。
關于Hologres內部表DDL語句的介紹詳情,請參見: