日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

CREATE TABLE創建分區表與復制表

更新時間:

本文介紹云原生數據倉庫 AnalyticDB MySQL 版CREATE TABLE建表語法。您將了解到如何創建分區表和復制表,以及如何定義表的分布鍵、分區鍵、索引、生命周期、冷熱數據分層等。

表的數據分布策略

建表前,您可以通過下圖中的示例,了解關于表的幾個重要概念,包括分片、分區、聚集索引。

image

語法

CREATE TABLE [IF NOT EXISTS] table_name
  ({column_name column_type [column_attributes] [ column_constraints ] [COMMENT 'column_comment']
  | table_constraints}
  [, ... ])
  [table_attribute]
  [partition_options]
  [storage_policy]
  [block_size]
  [engine]
  [rt_engine]
  [table_properties]
  [AS query_expr]
  [COMMENT 'table_comment']

column_attributes:
  [DEFAULT {constant | CURRENT_TIMESTAMP}]
  [AUTO_INCREMENT]

column_constraints:
  [{NOT NULL|NULL} ]
  [PRIMARY KEY]

table_constraints:
  [{INDEX|KEY} [index_name] (column_name,...)]
  [{INDEX|KEY} [index_name] (column_name->'$[*]')]
  [FULLTEXT [INDEX|KEY] [index_name] (column_name) [index_option]] [,...]
  [PRIMARY KEY [index_name] (column_name,...)]
  [CLUSTERED KEY [index_name] (column_name,...)]
  [[CONSTRAINT [symbol]] FOREIGN KEY (fk_column_name) REFERENCES pk_table_name (pk_column_name)][,...]
  [ANN INDEX [index_name] (column_name,...) [index_option]] [,...]

table_attribute:
  DISTRIBUTED BY HASH(column_name,...) | DISTRIBUTED BY BROADCAST

partition_options:
  PARTITION BY 
        {VALUE(column_name) | VALUE(date_format(column_name, 'format'))}
  LIFECYCLE N

storage_policy:
  STORAGE_POLICY= {'HOT'|'COLD'|'MIXED' {hot_partition_count=N}}

block_size:
  BLOCK_SIZE= VALUE

engine:
  ENGINE= 'XUANWU|XUANWU_V2'

參數

table_name、column_name、column_type、COMMENT

參數

說明

table_name

表名。表名以字母或下劃線(_)開頭,可包含字母、數字以及下劃線(_),長度為1到127個字符。

您可以使用db_name.table_name,指定在某個數據庫下創建表。

column_name

列名。列名以字母或下劃線(_)開頭,可包含字母、數字以及下劃線(_),長度為1到127個字符。

column_type

列的數據類型。AnalyticDB for MySQL支持的數據類型,請參見基礎數據類型復雜數據類型

COMMENT

為列或表添加備注信息。

column_attributes(默認值與自增列)

DEFAULT {constant | CURRENT_TIMESTAMP}

定義列的默認值。僅支持常量CURRENT_TIMESTAMP函數。不支持其他函數和變量表達式。

如果未指定默認值,則列的默認值為NULL

AUTO_INCREMENT

定義自增列。 自增列的數據類型必須是BIGINT類型。

AnalyticDB for MySQL為自增列提供唯一值,但自增列的值不是順序遞增,且不支持從1開始遞增

column_constraints(非空與主鍵)

NOT NULL

定義了NOT NULL的列,值不能為NULL。不定義NOT NULL或定義了NULL時,值可以為NULL

PRIMARY KEY

定義主鍵。在列約束(column_constraints)中,只能定義單一列作為主鍵,例如id BIGINT NOT NULL PRIMARY KEY。如需多個列作為主鍵,請在表約束(table_constraints)中定義復合主鍵。

table_constraints(索引)

AnalyticDB for MySQL支持多種索引,包括INDEX索引、主鍵索引、聚集索引、外鍵索引、全文索引、向量索引等。一個表可以有一種或多種索引。

INDEX | KEY

定義普通索引。INDEX和KEY作用相同。

默認情況下,AnalyticDB for MySQL自動為全表所有列創建索引。但是,如果您在建表時手動指定為某一列或某幾列創建索引(例如INDEX (id)),則AnalyticDB for MySQL不會再為表中其他列自動創建索引。

PRIMARY KEY

定義主鍵索引。

基本使用:

  • 每個表只能有一個主鍵。

  • 主鍵可以是單個列或多個列的組合,例如PRIMARY KEY (id)PRIMARY KEY (id,name)

  • 主鍵中必須包含分布鍵分區鍵,并且建議將分布鍵分區鍵放在主鍵的前部

注意事項

  • 無主鍵的表,不能執行DELETE和UPDATE操作。

  • 未定義主鍵,會有以下行為:

    • 如果未定義主鍵和分布鍵,AnalyticDB for MySQL自動添加一個列__adb_auto_id__作為表的主鍵和分布鍵

    • 如果未定義主鍵,但定義了分布鍵,AnalyticDB for MySQL不會自動添加主鍵

  • 建表后,不能增加、減少或變更主鍵列。

調優建議:推薦使用數值類型的列作為主鍵,并盡量減少主鍵包含的列的個數,以獲得較好的性能。

說明

主鍵包含的列過多,可能導致:

  • 數據寫入時,AnalyticDB for MySQL檢查主鍵是否重復,將消耗更多的CPU和IO資源。

  • 主鍵索引將占用更多的磁盤空間。您可以使用空間分析功能,查看主鍵索引占用的磁盤空間。

  • 主鍵包含的列越多,BUILD任務會越慢。

CLUSTERED KEY

定義聚集索引。聚集索引是分區級別的,它決定了數據的物理存儲順序,即分區內的數據會按聚集索引的鍵值進行排序,按順序存儲。聚集索引的鍵值相同或相近的數據存儲在相同或相近數據塊。在范圍查詢或等值查詢中,如果查詢條件與聚集索引列一致,存儲引擎可快速讀取連續的數據塊,這樣可以減少磁盤的I/O,加快數據讀取的速度。

聚集索引示意圖

image

適用場景:

聚集索引既適用于范圍查詢,也適用于等值查詢。高頻出現在范圍查詢條件和等值查詢條件的列,可以作為聚集索引。

當查詢條件涉及的列與聚集索引列完全一致或部分一致時,可以加快數據讀取的效率。例如,在SaaS類應用中,用戶通常只訪問自己的數據,用戶ID可以作為聚集索引,保證同一用戶ID的數據連續存儲在相同或相鄰的數據塊中,數據讀取更快。

基本使用:

  • 每個表中只能有一個聚集索引。

  • 聚集索引可以基于單個列創建(例如CLUSTERED KEY index(id)),也可以基于多個列創建(例如CLUSTERED KEY index(id,name))。當聚集索引鍵涉及多個列時,數據會先根據第一個列的值排序,在第一個列的值相同時,按第二個列的值進行次級排序。所以CLUSTERED KEY index(id,name)CLUSTERED KEY index(name,id)是不同的聚集索引。

  • 如果字段值較長,例如長達十幾KB或幾十KB的字符串,則不建議聚集索引采用該字段,避免影響排序性能。

FULLTEXT INDEX | FULLTEXT KEY

定義全文索引。FULLTEXT INDEX與FULLTEXT KEY作用相同。關于全文索引的更多介紹,請參見創建全文索引

語法與參數說明

語法[FULLTEXT [INDEX|KEY] [index_name] (column_name) [index_option]] [,...]

參數說明:

  • index_name:全文索引名稱。

  • column_name:全文索引的列。列的類型必須是VARCHAR類型。

  • index_option:指定全文索引的分詞器和自定義詞典。非必填。

FOREIGN KEY

定義外鍵索引。外鍵索引用于消除不必要的JOIN,關于JOIN消除的詳情,請參見通過主外鍵約束消除多余的JOIN

語法與參數說明

版本說明:

AnalyticDB for MySQL集群內核版本需為3.1.10或以上

說明

查看企業版湖倉版集群的內核版本,請執行SELECT adb_version();。如需升級內核版本,請聯系技術支持。

語法[[CONSTRAINT [symbol]] FOREIGN KEY (fk_column_name) REFERENCES pk_table_name (pk_column_name)][,...]

參數說明:

  • symbol:可選項,外鍵約束名,在表內唯一。不指定時,解析器將會在外鍵列名后面自動補充后綴_fk用作外鍵約束名。

  • fk_column_name:指定外鍵列。外鍵列需要在建表語句中定義。

  • pk_table_name:指定主表名。主表必須已存在。

  • pk_column_name:指定外鍵約束列,該列必須存在且為主表的主鍵列。

基本使用:

  • 每個表可以有多個外鍵索引。

  • 不支持復合的外鍵索引,即不支持多個列組成的外鍵索引,例如:FOREIGN KEY (sr_item_sk, sr_ticket_number) REFERENCES store_sales(ss_item_sk,d_date_sk)

  • AnalyticDB for MySQL不會進行數據的約束檢查。您需要自行確保主表的主鍵和從表的外鍵之間的數據約束關系。

  • 外表不支持創建外鍵約束。

ANN INDEX

定義向量索引。關于向量索引和向量檢索的更多介紹,請參見向量檢索

語法與參數說明

語法[ANN INDEX [index_name] (column_name,...) [index_option]] [,...]

參數說明:

  • index_name:向量索引的名稱。

  • column_name:向量列的列名。向量列的類型需為array<float>、array<smallint>、array<byte>,且需指定向量列的維數,向量列的定義示例:feature array<float>(4)

  • index_option:向量索引的屬性。

    • algorithm:向量距離計算公式使用的算法。取值僅支持HNSW_PQ,適用于單表數據量在百萬級別到千萬級別之間,對向量維度敏感的中等規模數據量場景。

    • dis_function:向量距離計算公式。取值僅支持SquaredL2。計算公式:(x1-y1)^2+(x2-y2)^2+…

JSON INDEX

定義JSON索引或JSON Array索引。更多介紹,請參見JSON索引

語法與參數說明

JSON索引

版本說明:

  • 3.1.5.10及以上內核版本的集群,創建表后不會自動創建JSON索引,您需手動創建JSON索引。

  • 3.1.5.10以下內核版本的集群,創建表后會自動為JSON列創建JSON索引。

說明

查看企業版湖倉版集群的內核版本,請執行SELECT adb_version();。如需升級內核版本,請聯系技術支持。

語法[INDEX [index_name] (column_name|column_name->'$.json_path'.)]

參數說明:

  • index_name:索引的名稱。

  • column_name|column_name->'$.json_path':

    • column_name:JSON索引的列。

    • column_name->'$.json_path':JSON索引的列及其指定的屬性鍵。每一個JSON索引只能有一個JSON列的一個屬性鍵。

      重要
      • 僅3.1.6.8及以上內核版本的集群支持column_name->'$.json_path

        • 查看企業版基礎版湖倉版集群的內核版本,請執行SELECT adb_version();。如需升級內核版本,請聯系技術支持。

        • 查看和升級數倉版集群的內核版本,請參見查看和升級版本

      • 為JSON列中的指定屬性鍵創建索引時,若該JSON列已存在INDEX索引,需先刪除該列的INDEX索引,否則會報錯。

JSON Array索引

版本說明:

3.1.10.6及以上內核版本的集群支持創建JSON Array索引。

說明

查看企業版湖倉版集群的內核版本,請執行SELECT adb_version();。如需升級內核版本,請聯系技術支持。

語法[INDEX [index_name] (column_name->'$[*]')]

參數說明:

  • index_name:索引的名稱。

  • column_name->'$[*]':column_name為JSON Array索引的列。例如:vj->'$[*]'表示為vj列創建JSON Array索引。

table_attribute(分布鍵)

table_attribute決定了表的類型是普通表還是復制表。

  • DISTRIBUTED BY HASH,定義表為普通表。普通表能夠充分利用分布式系統的查詢優勢,提高查詢效率。普通表可存儲的數據量較大,通常可以存儲千萬條甚至千億條數據。

  • DISTRIBUTED BY BROADCAST,定義表為復制表。復制表會在集群的每個分片存儲一份數據,因此建議每個復制表中的數據量不宜太大,最好不超過2萬行。

DISTRIBUTED BY HASH (column_name,...)

定義表的分布鍵。定義了分布鍵的表,又稱普通表。AnalyticDB for MySQL對分布鍵的值進行哈希計算,根據計算得出的哈希值,將不同行的數據分散到不同分片(Shard),有利于提高可擴展性和查詢性能。

數據分片示意圖

image

基本用法:

  • 每個表只能有一個分布鍵

  • 一個分布鍵可以包含一個列或者多個列。

  • 分布鍵中的列,必須包含在主鍵中。例如,分布鍵為customerid,那么主鍵也需要包含customerid。

注意事項

  • 創建表時未定義分布鍵,系統會根據表是否含有主鍵進行如下處理:

    • 如果MySQL表含有主鍵,AnalyticDB for MySQL默認將主鍵作為分布鍵

    • 如果MySQL表不含有主鍵,AnalyticDB for MySQL自動添加一個__adb_auto_id__作為主鍵和分布鍵

  • 建表后,不能增加、減少或變更分布鍵列。如果需要修改分布鍵,需重新建表并遷移數據,具體操作請參見ALTER TABLE

調優建議:

  • 建議分布鍵包含盡可能少的列,使得分布鍵在各種復雜查詢中更加通用。

  • 盡可能選擇高頻率出現在查詢條件中,且值分布均勻的列作為分布鍵,例如交易ID、設備ID、用戶ID或者自增列作為分布鍵。但如果查詢條件非常局限,例如列a雖然值分布均勻且高頻出現在查詢條件中,但總是以a=3的形式出現在查詢條件中,那么列a作為分布鍵會造成數據熱點,列a就不適合作為分布鍵。

  • 盡可能將需要Join的列作為分布鍵。參與Join的兩個表,按相同的分布鍵(Join列)進行數據分布,使得兩個表相同鍵值的數據被分布到同一分片,可直接在同一分片進行Join操作,無需在分片之間進行數據傳輸,能夠有效減少查詢過程中的數據重分布,提升查詢性能。例如,需要按照顧客維度查看歷史訂單信息,可以選擇customer_id作為分布鍵。

  • 盡量不要選擇日期、時間和時間戳類型的列作為分布鍵,寫入時容易發生傾斜,影響寫入性能,且多數查詢通常是限定了日期或時間段,如:查詢最近一天或一個月的數據,可能會導致要查詢的數據只存在于一個節點上,無法充分利用分布式數據庫中所有節點的處理能力。建議將日期、時間類型的列作為分區鍵,具體請參見partition_options(分區鍵與生命周期)

  • 您可以利用數據建模診斷功能查看表的分布鍵是否合理、數據是否傾斜。詳情請參見存儲空間診斷

DISTRIBUTED BY BROADCAST

定義復制表。復制表會在集群的每個節點存儲一份該表的全量數據,因此建議復制表的數據量不宜太大。

優點:Join查詢時,無需將復制表的數據在不同節點之間傳輸。當查詢并發量較大時,可以有效降低網絡傳輸的開銷,提高集群穩定性。

缺點:當復制表數據發生變更(插入、變更或刪除)時,變更會被廣播到集群的所有節點,確保所有節點上具有一致的數據副本,會影響整體寫入性能。因此不建議對復制表進行頻繁的增刪改等操作。

partition_options(分區鍵與生命周期)

如果設置了分布鍵后,單個分片的數據量較大,您可以定義分區鍵將分片上的數據劃分為不同的分區,加快數據過濾速度,提高查詢性能。

為什么要定義分區

  • 分區可以加快數據過濾速度,提高查詢性能。

    • 分區裁剪。只查詢相關數據的分區,跳過無關分區,減少數據掃描,提高查詢速度。

    • 索引的掃描性能較好。當索引的行數過大,例如超過5000萬行,索引的掃描效率就會下降。索引是分區級別的,即每個分區有一個獨立的索引。如果表沒有定義數據分區,那么表的所有數據都在一個分區中,數據量超過千萬時,索引掃描效率下降。當表定義了數據分區,數據分散在不同分片的不同分區時,每個分區索引的行數可以控制在千萬行內,可以保證掃描的性能。

    • 提高Build的效率。Build用于將實時數據轉換成歷史數據,過程中會構建分區、構建索引、清理冗余數據等。Build任務完成,新的索引才能生效。當表沒有定義分區時,每次Build任務都是全表Build,數據越多,Build越慢,新的索引就會越晚生效,從而影響查詢性能。當表定義了分區,每次只Build有數據變更的分區,Build的時間就會縮短。

  • 分區結合生命周期(LIFECYCLE),可以實現數據的生命周期管理。

  • 分區結合存儲策略(storage_policy),可以實現冷熱數據分層。

數據分區與生命周期的示意圖

image

PARTITION BY

指定分區鍵。

語法PARTITION BY VALUE {(column_name) | (DATE_FORMAT(column_name, 'format'))} LIFECYCLE n

參數說明

  • column_name:分區鍵。PARTITION BY VALUE(column_name)表示使用column_name的值來分區。分區鍵的數據類型可以是數值類型、日期時間類型或表示數字的字符串類型。

  • DATE_FORMAT(column_name, 'format'):使用DATE_FORMAT函數將日期時間類型的列轉換成指定的日期格式,再對數據分區。format僅支持年、月、日,即%Y、%y、%Y%m、%y%m、%Y%m%d、%y%m%d。建表后,format支持修改,修改方法請參見ALTER TABLE

注意事項

  • 3.2.1.0以下內核版本的集群,使用PARTITION BY定義分區時,必須同時定義生命周期LIFECYCLE n),否則會報錯。

  • 3.2.1.0 及以上內核版本的集群,使用PARTITION BY定義分區時,生命周期LIFECYCLE n為可選參數。若未配置,則分區數據不會被清理。

  • 建表后,不能增加分區鍵,也不支持增加、減少或變更修改分區鍵中的列。如果需要增加或修改分區鍵,請重新建表并遷移數據,具體操作請參見ALTER TABLE

調優建議:

  • 建議使用日期時間類型的字段作為分區鍵。

  • 分區太大或太小都會影響查詢性能和寫入性能,甚至影響集群的穩定性。建議的分區內數據行數以及查看分區是否合理,請參見分區表診斷

  • 不建議頻繁更新歷史分區的數據,例如,如果每天頻繁更新多個歷史分區,應考慮使用的分區鍵是否合理。

LIFECYCLE n

LIFECYCLE需要與PARTITION BY一起使用,用于管理分區的生命周期。AnalyticDB for MySQL會根據分區鍵的值,從大到小對分區排序,保留前n個分區,超出n的分區將被刪除。您可以利用LIFECYCLE定義數據的保留時長。

  • 3.2.1.1以下內核版本,LIFECYCLE n定義每個分片最多保留n個分區。以分片級管理分區的生命周期時,在數據分布不均或數據量極少的情況下,可能會出現保留的總分區數多于n的情況。

  • 3.2.1.1及以上內核版本,升級后新建表按照表級管理分區的生命周期,LIFECYCLE n定義每個表最多保留n個分區。升級前已創建的表仍按照分片級管理分區的生命周期,LIFECYCLE n定義每個分片最多保留n個分區。

示例:

例如,PARTITION BY VALUE (DATE_FORMAT(date, '%Y%m%d')) LIFECYCLE 30表示,將date列轉換為yyyyMMdd的格式并對數據分區,最多保留30個分區。假設第1天的數據寫入分區20231201,第2天的數據寫入分區20231202,依次類推,第30天的數據寫入分區20231230。當第31天的數據寫入分區20231231時,因為最多只能保留30個分區,所以最小的分區(即分區20231201)將會被自動刪除。

storage_policy(存儲策略)

企業版、基礎版及湖倉版數倉版彈性模式集群版(新版)支持指定數據的存儲策略。不同的存儲策略,數據的讀寫性能不同,數據的存儲成本也不同。

取值說明

  • hot(默認值): 熱存儲,即全表所有分區的數據都存儲在SSD。性能最好,但存儲成本也最高。

  • cold: 冷存儲,即全表所有分區的數據都在OSS。性能比熱存儲差,但存儲成本最低。

  • mixed: 冷熱混合存儲,又叫冷熱分層存儲,即查詢頻率高的分區數據(又稱熱數據)存儲在SSD,查詢頻率低的分區數據(又稱冷數據)存儲在OSS,既降低存儲成本,又保證查詢性能。選擇mixed時,必須同時使用PARTITION BY定義分區并使用hot_partition_count指定熱分區的數量。如未定義分區,mixed不生效,數據實際會存儲在SSD。

    冷熱混合存儲示意圖

    image

hot_partition_count(熱分區)

STORAGE_POLICY='mixed'時,需要通過hot_partition_count=n(n為正整數)定義熱分區的數量。AnalyticDB for MySQL將根據分區鍵的值,從大到小對分區排列,最大的n個分區為熱分區,其他分區為冷分區。

說明

如果存儲策略(STORAGE_POLICY)的取值不是mixed,則不支持指定hot_partition_count=n,否則會報錯。

block_size(數據塊)

Block,又叫數據塊,是數據讀寫的最小IO單元。block_size用于指定列式存儲中每個block存儲的數據行數。調整block_size會增加或減少每次IO讀取的行數,具體的影響需要結合查詢特征,例如點查詢時,若block_size較大,存儲讀block的效率會降低,此時可以適當調小block_size。

默認值說明:

  • 復制表的block_size默認值為4096。

  • 彈性模式集群版(新版)單機版(計算資源為32核以下),block_size默認值為8192。

  • 其它情況下,block_size默認值為32760。當block_size為32760時,在SHOW CREATE TABLE 時,不顯示block_size。

重要

若不熟悉列式存儲原理,建議不要更改block_size。

engine(存儲引擎)

指定AnalyticDB for MySQL內表的存儲引擎類型,用于歷史數據分析。

取值說明:

  • XUANWU(默認值):若建表時未顯式指定ENGINE,則默認選擇該值。

  • XUANWU_V2:XUANWU引擎基礎上研發的新一代存儲引擎。僅V3.2.0及以上內核版本支持XUANWU_V2。需提前開啟XUANWU_V2引擎,方法請參見XUANWU_V2引擎介紹

說明
  • 3.1.9.5以下內核版本的集群,如果在創建內表時顯式指定了ENGINE='XUANWU',則需同時顯示指定table_properties='{"format":"columnstore"}',否則建表會失敗。

  • 了解玄武存儲引擎的介紹,請參見玄武分析型存儲引擎

AS query_expr(CTAS)

CREATE TABLE AS query_expr表示創建表并將SELECT查詢結果寫入新創建的表。具體用法,請參見CREATE TABLE AS SELECT(CTAS)

示例

新建分區表并設置生命周期

新建普通表customer,login_timecustomer_idphone_num為復合主鍵, customer_id為分布鍵,login_time為分區鍵,分區的生命周期為30。

所有分區,按分區鍵login_time的值(例如,20231202,20231201等)從大到小排序,僅保留分區鍵值最大的30個分區,當第31個分區數據寫入時,自動刪除最小的第1個分區。

假設,第1天login_time的值為20231201,第二天login_time的值為20231202,依次類推,第30天login_time的值為20231230。當第31天login_time為20231231的數據寫入時,最小的分區(即'20231201'分區)數據將會被自動刪除,從而實現只保留最近30天的數據。

CREATE TABLE customer (
  customer_id BIGINT NOT NULL COMMENT '顧客ID',
  customer_name VARCHAR NOT NULL COMMENT '顧客姓名',
  phone_num BIGINT NOT NULL COMMENT '電話',
  city_name VARCHAR NOT NULL COMMENT '所屬城市',
  sex INT NOT NULL COMMENT '性別',
  id_number VARCHAR NOT NULL COMMENT '身份證號碼',
  home_address VARCHAR NOT NULL COMMENT '家庭住址',
  office_address VARCHAR NOT NULL COMMENT '辦公地址',
  age INT NOT NULL COMMENT '年齡',
  login_time TIMESTAMP NOT NULL COMMENT '登錄時間',
  PRIMARY KEY (login_time,customer_id,phone_num)
 )
DISTRIBUTED BY HASH(customer_id)
PARTITION BY VALUE(DATE_FORMAT(login_time, '%Y%m%d')) LIFECYCLE 30
COMMENT '客戶信息表';                   

新建表(未定義分布鍵)

未定義分布鍵,自動將主鍵作為分布鍵

表定義了主鍵但未定義分布鍵,AnalyticDB for MySQL默認將主鍵作為分布鍵。

CREATE TABLE orders (
  order_id BIGINT NOT NULL COMMENT '訂單ID',
  customer_id INT NOT NULL COMMENT '顧客ID',
  order_status VARCHAR(1) NOT NULL COMMENT '訂單狀態',
  total_price DECIMAL(15, 2) NOT NULL COMMENT '訂單金額',
  order_date DATE NOT NULL COMMENT '訂單日期',
  PRIMARY KEY(order_id,order_date)
);

查詢建表語句,可以看到主鍵order_id和order_date被采納為分布鍵。

SHOW CREATE TABLE orders;
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                                                  | 
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| orders  | CREATE TABLE `orders` (                                                                                                                       |
|         | `order_id` bigint NOT NULL COMMENT '訂單ID',                                                                                                   |
|         | `customer_id` int NOT NULL COMMENT '顧客ID',                                                                                                   |
|         | `order_status` varchar(1) NOT NULL COMMENT '訂單狀態',                                                                                         | 
|         | `total_price` decimal(15, 2) NOT NULL COMMENT '訂單金額',                                                                                      |
|         | `order_date` date NOT NULL COMMENT '訂單日期',                                                                                                 |
|         | PRIMARY KEY (`order_id`,`order_date`)                                                                                                         |
|         | ) DISTRIBUTED BY HASH(`order_id`,`order_date`) INDEX_ALL='Y' STORAGE_POLICY='HOT' ENGINE='XUANWU' TABLE_PROPERTIES='{"format":"columnstore"}'  |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

未定義主鍵,自動增加主鍵

表未定義主鍵,也未定義分布鍵,AnalyticDB for MySQL將添加一個列__adb_auto_id__作為主鍵和分布鍵。

CREATE TABLE orders_new (
  order_id BIGINT NOT NULL COMMENT '訂單ID',
  customer_id INT NOT NULL COMMENT '顧客ID',
  order_status VARCHAR(1) NOT NULL COMMENT '訂單狀態',
  total_price DECIMAL(15, 2) NOT NULL COMMENT '訂單金額',
  order_date DATE NOT NULL COMMENT '訂單日期'
);

查詢建表語句,可以看到表中自動增加一個自增列__adb_auto_id__,該自增列作為表的主鍵和分布鍵。

SHOW CREATE TABLE orders_new;
+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                  | 
+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| orders_new  | CREATE TABLE `orders_new` (                                                                                                                   |
|             | `__adb_auto_id__` bigint AUTO_INCREMENT,                                                                                                      |
|             | `order_id` bigint NOT NULL COMMENT '訂單ID',                                                                                                   |
|             | `customer_id` int NOT NULL COMMENT '顧客ID',                                                                                                   |
|             | `order_status` varchar(1) NOT NULL COMMENT '訂單狀態',                                                                                         | 
|             | `total_price` decimal(15, 2) NOT NULL COMMENT '訂單金額',                                                                                      |
|             | `order_date` date NOT NULL COMMENT '訂單日期',                                                                                                 |
|             | PRIMARY KEY (`__adb_auto_id__`)                                                                                                               |
|             | ) DISTRIBUTED BY HASH(`__adb_auto_id__`) INDEX_ALL='Y' STORAGE_POLICY='HOT' ENGINE='XUANWU' TABLE_PROPERTIES='{"format":"columnstore"}'        |
+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

新建表(未定義分區鍵)

新建表supplier,supplier_id為自增列,分布鍵為supplier_id,按照supplier_id值進行HASH分片。

CREATE TABLE supplier (
  supplier_id BIGINT AUTO_INCREMENT PRIMARY KEY,
  supplier_name VARCHAR,
  address INT,
  phone VARCHAR
) 
DISTRIBUTED BY HASH(supplier_id);

定義冷熱數據存儲策略

定義冷(COLD)存儲策略

CREATE TABLE item (
  order_id BIGINT NOT NULL,
  item_id INT NOT NULL,
  quantity DECIMAL(15, 2) NOT NULL,
  discount DECIMAL(15, 2) NOT NULL,
  shipdate DATE NOT NULL,
  PRIMARY KEY (order_id,item_id,shipdate)
) 
DISTRIBUTED BY HASH(item_id) 
PARTITION BY VALUE(date_format(shipdate, '%Y%m')) LIFECYCLE 200 
STORAGE_POLICY='COLD';

定義熱(HOT)存儲策略

CREATE TABLE item (
  order_id BIGINT NOT NULL,
  item_id INT NOT NULL,
  quantity DECIMAL(15, 2) NOT NULL,
  discount DECIMAL(15, 2) NOT NULL,
  shipdate DECIMAL NOT NULL,
  PRIMARY KEY (order_id,item_id,shipdate)
) 
DISTRIBUTED BY HASH(item_id) 
PARTITION BY VALUE(date_format(shipdate, '%Y%m')) LIFECYCLE 200 
STORAGE_POLICY='HOT';

定義混合(MIXED)存儲策略,同時指定熱分區數量為16個

CREATE TABLE item (
  order_id BIGINT NOT NULL,
  item_id INT NOT NULL,
  quantity DECIMAL(15, 2) NOT NULL,
  discount DECIMAL(15, 2) NOT NULL,
  shipdate DATE NOT NULL,
  PRIMARY KEY (order_id,item_id,shipdate)
) 
DISTRIBUTED BY HASH(item_id) 
PARTITION BY VALUE(date_format(shipdate, '%Y%m')) LIFECYCLE 200  
STORAGE_POLICY='MIXED' HOT_PARTITION_COUNT=16;

定義全文索引

為content列創建全文索引,索引名稱為fidx_c。

CREATE TABLE fulltext_tb (
  id INT,
  content VARCHAR,
  keyword VARCHAR,
  FULLTEXT INDEX fidx_c(content),
  PRIMARY KEY (id)
) 
DISTRIBUTED BY HASH(id);

關于創建和變更全文索引的更多內容,請參見創建全文索引

關于全文檢索,請參見全文檢索

定義向量索引

定義short_feature、float_feature為向量列,類型是array<float>,向量維數為4。

根據short_feature創建向量索引short_feature_index,根據float_feature創建向量索引float_feature_index。

CREATE TABLE fact_tb (  
  xid BIGINT NOT NULL,  
  cid BIGINT NOT NULL,  
  uid VARCHAR NOT NULL,  
  vid VARCHAR NOT NULL,  
  wid VARCHAR NOT NULL,  
  short_feature array<smallint>(4),  
  float_feature array<float>(4),  
  ann index short_feature_index(short_feature), 
  ann index float_feature_index(float_feature),  
  PRIMARY KEY (xid, cid, vid)
) 
DISTRIBUTED BY HASH(xid) PARTITION BY VALUE(cid) LIFECYCLE 4;

更多關于向量索引和向量檢索的內容,請參見向量檢索

定義外鍵索引

新增一個名為store_returns的表,通過使用外鍵語法FOREIGN KEYsr_item_sk列和customer表的主鍵列customer_id關聯起來。

CREATE TABLE store_returns (
  sr_sale_id BIGINT NOT NULL PRIMARY KEY,
  sr_store_sk BIGINT,
  sr_item_sk BIGINT NOT NULL,
  FOREIGN KEY (sr_item_sk) REFERENCES customer (customer_id)
);

定義JSON Array索引

為vj列創建JSON Array索引,索引名稱為idx_vj。

CREATE TABLE json(
  id INT,
  vj JSON,
  INDEX idx_vj(vj->'$[*]')
)
DISTRIBUTED BY HASH(id);

關于創建和變更JSON Array索引的更多內容,請參見創建JSON Array索引JSON Array索引

常見問題

列屬性和列約束

自增列是從1開始遞增嗎?值是唯一的嗎?

自增列的值不是順序遞增,也不支持從1開始遞增。但自增列的值都是唯一值。

分布鍵、分區鍵與生命周期

分布鍵和分區鍵有什么區別?

根據分布鍵值的HASH結果不同,數據被分散到不同的分片上。在分片上,根據分區鍵值的不同,數據被劃分為不同的分區。示意圖如下。

image

建表時,是否必須指定分布鍵?

  • 創建分區表,不是必須手動指定分布鍵。如果未手動指定分布鍵,AnalyticDB for MySQL會采納主鍵作為分布鍵。無主鍵時,自動生成一列__adb_auto_id__作為分布鍵和主鍵。

  • 創建復制表,不需要指定分布鍵,但需要指定DISTRIBUTED BY BROADCAST,表示每個存儲節點都存儲一份全量數據。

在集群變配時,是否改變分片數?

變配不會改變集群的分片數(Shard數量)。

如何查詢表的分區信息?

執行SQL查詢表的分區信息:

SELECT partition_id, --分區名
 row_count, -- 分區總行數
 local_data_size, --分區本地存儲所占用空間大小
 index_size, -- 分區的索引大小
 pk_size, --分區的主鍵索引大小
 remote_data_size --分區的遠端存儲所占用空間大小
FROM information_schema.kepler_partitions
WHERE schema_name = '$DB'
 AND table_name ='$TABLE' 
 AND partition_id > 0;

創建分區表后,為什么查不到分區信息?

創建分區表后,查不到分區信息主要有兩個原因:

  • 建表時,只是通過定義分區鍵設置了數據分區的規則,并沒有開始創建分區。分區由分區鍵的鍵值決定。如果表還沒寫入數據,分區鍵值為空,不會創建分區。

  • 分區不是實時構建的。當寫入的數據BUILD完成后,才能查看到分區信息。

解決方法:

請先寫入數據,并等待BUILD任務完成。BUILD任務完成后,可以查看分區信息。

說明

BUILD的詳細介紹以及查詢BUILD進度,請參見BUILD

分區鍵的數據類型有什么要求?

分區鍵的數據類型可以是數值類型、日期時間類型或表示數字的字符串類型。除此以外的數據類型,可能導致數據寫入報錯。

如果寫入數據時,遇到報錯partition format function error,說明寫入分區鍵的值不符合數據類型的要求。

指定分區鍵時,能否使用除DATE_FORMAT以外的其他函數,例如PARTITION BY VALUE(FROM_UNIXTIME(col,'format'))?

不能。定義分區鍵僅支持兩種方法:PARTITION BY VALUE(column)和PARTITION BY VALUE(DATE_FORMAT(column,'format'))。使用其他函數會報錯。

如何查看分區表的生命周期?

通過SHOW CREATE TABLE <table_name>,查看建表語句。建表語句中顯示分區表的生命周期。

已設置數據只保留30天(即設置LIFECYCLE為30),為什么還是可以查到30天以前的數據?

可能有兩個原因:

  • 分區剛剛過期,尚未被刪除。過期的分區數據不會被立即刪除。當該表的BUILD任務完成后,過期的分區數據才會被刪除。

  • 3.2.1.1以下內核版本中創建的表,LIFECYCLE的定義為一個分片上保留多少個分區。當一個分片上,實際分區數小于LIFECYCLE設定值時,可能出現該現象。在3.2.1.1及以上內核版本中新建的表,不存在該問題。

    例如:

    • 數據分布不均。假設按日期分區,分片1有分區20231201、20231202、依次類推到20231230;分片2有分區20231202、20231203、依次類推到20231231。分片1和分片2上的分區數均為30,沒有超過LIFECYCLE的設定值(30),因此分片1和分片2都不會刪除分區。查詢數據時,可以查到日期為20231201~20231231的數據。

    • 長時間無數據寫入。假設按日期分區,分片1已有分區20231201、20231202、20231203和20231204,并且在20231204后該表沒有新的分區數據寫入。此時分片1僅有4個分區,沒有超過LIFECYCLE的設定值(30),因此不會刪除分區。在20231231后,仍然可以查到日期為20231201的數據。

超過生命周期的分區數據,會被立即清理嗎?

不會。分區不是實時構建和清理的。表的某個分區過期后,該表需要完成BUILD,分區才會被清理。

索引

如何查詢表的聚集索引?

通過SHOW CREATE TABLE查詢建表語句中定義的聚集索引。

是否支持唯一索引(UNIQUE INDEX)?

AnalyticDB for MySQL不支持唯一索引(UNIQUE INDEX)。但AnalyticDB for MySQL的主鍵索引就是唯一索引,可以確保主鍵值在表中是唯一的。

列存

建表語句中的TABLE_PROPERTIES='{"format":"columnstore"}'是什么意思?

TABLE_PROPERTIES='{"format":"columnstore"}'是固定取值,表示ENGINE中的數據是列存格式。建表時您無需手動指定該屬性。

其他

建表后,哪些參數可以通過ALTER TABLE變更?

ALTER TABLE支持變更以下參數:

  • table_name、column_name、column_type、COMMENT

  • 增加和刪除列(主鍵列除外)

  • 列的默認值

  • NOT NULL變更為NULL

  • 增加和刪除INDEX索引

  • 分區函數的日期格式

  • 生命周期

  • 存儲策略

具體用法請參見ALTER TABLE

其他參數在建表后無法變更。

一個集群最多能夠創建多少個表?

一個AnalyticDB for MySQL集群的表數量上限如下:

  • 企業版集群:80000/(分片數/預留資源節點數/3)分片數/預留資源節點數/3向上取整。

    增加預留資源節點數,可提高內表數量的上限,增加預留資源節點數請參見企業版與基礎版擴縮容

  • 基礎版集群:80000/(分片數/預留資源節點數)(分片數/預留資源節點數)向上取整。

    增加預留資源節點數,可提高內表數量的上限,增加預留資源節點數請參見企業版與基礎版擴縮容

  • 數倉版預留模式集群(具備1~20個節點組):80000/(分片數/節點組數量)分片數/節點組數量向上取整。

    增加節點組數量,可提高內表數量的上限,增加節點組數量請參見數倉版擴縮容

  • 數倉版彈性模式集群的內表數量上限:[80000/(分片數/EIU數量)]*2分片數/EIU數量向上取整。

    EIU又叫彈性IO資源。增加EIU數量,可提高內表數量的上限,增加EIU數量請參見彈性IO資源(EIU)擴容

  • 湖倉版集群的內表數量上限:[80000/(分片數/存儲預留資源的組數)]*2。一組存儲預留資源為24 ACU。假設集群的存儲預留資源為48 ACU,則存儲預留資源的組數為2。

    擴容存儲預留資源,可提高內表數量的上限,擴容請參見湖倉版擴縮容

  • 企業版、基礎版及湖倉版數倉版彈性模式集群的外表數量上限:50萬。

說明

查詢分片數(Shard數量):SELECT COUNT(1) FROM information_schema.kepler_meta_shards;。不支持增加或減少分片數。關于數據分片的詳細介紹,請參見分片(Shard)

AnalyticDB for MySQL的默認字符集是什么?

AnalyticDB for MySQL默認的字符集為utf-8,相當于MySQL的utf8mb4字符集,暫不支持其他字符集。

常見報錯

partition number must larger than 0

原因:建表語句中定義了分區,但未設置分區的生命周期。

報錯的建表語句示例如下:

CREATE TABLE test (
  id INT COMMENT '',
  name VARCHAR(10) COMMENT '',
  PRIMARY KEY (id, name)
) 
DISTRIBUTED BY HASH(id) PARTITION BY VALUE(name);

解決方法:在建表語句中定義分區的生命周期,正確的示例如下。

CREATE TABLE test (
  id INT COMMENT '',
  name VARCHAR(10) COMMENT '',
  PRIMARY KEY (id, name)
) 
DISTRIBUTED BY HASH(id) PARTITION BY VALUE(name) LIFECYCLE 30;
說明

僅 3.2.1.0 以下內核版本的集群會出現該報錯。

Only 204800 partition allowed, the number of existing partition=>196462

原因:AnalyticDB for MySQL集群分區數量的上限默認為102400。分區數量超過上限,會出現該報錯。

查詢集群的分區數量,方法如下。

SELECT count(partition_id)
FROM information_schema.kepler_partitions
WHERE partition_id > 0;

解決方法:您可以調整分區的粒度。例如,按天分區改為按月分區。修改分區粒度的操作,請參見ALTER TABLE

partition column 'XXX' is not found in primary index=> [YYY]

原因:主鍵需包含分布鍵和分區鍵。如果主鍵未包含分區鍵,會出現該報錯。

SQL錯誤示例1:

CREATE TABLE test (
  id INT COMMENT '',
  name VARCHAR(10) COMMENT '',
  PRIMARY KEY (id)
) 
DISTRIBUTED BY HASH(id) PARTITION BY VALUE(name) LIFECYCLE 30;

如果未指定主鍵和分布鍵,也會出現該報錯。因為建表未指定主鍵和分布鍵時,AnalyticDB for MySQL會自動生成一列__adb_auto_id__,作為主鍵和分布鍵。此時主鍵只有__adb_auto_id__,因為不包含分區鍵,所以報錯。

SQL錯誤示例2:

CREATE TABLE test (
  id INT COMMENT '',
  name VARCHAR(10) COMMENT ''
) 
PARTITION BY VALUE(name) LIFECYCLE 30;

解決方法:請將分區鍵添加到主鍵中。

SemanticException:only 5000 table allowed

原因:AnalyticDB for MySQL集群有表數量上限,超過上限,會出現該報錯。不同產品系列不同產品規格的表數量上限不同,具體請參見內表數量的最大值

解決方法:

  • 刪除無用的表。

  • 將多張表合并為一張表。

unsigned expr not supported

原因:AnalyticDB for MySQL不支持UNSIGNED屬性,即不支持無符號數。

解決方法:建表語句的列屬性中不定義UNSIGNED屬性。您需要自己在業務代碼中實現非負數的約束。

相關文檔