本文將為您介紹Sequence的相關概念和支援的類型。
PolarDB-X 1.0全域唯一數字序列(64位元字,對應MySQL中Signed BIGINT類型,以下簡稱為Sequence)的主要目標是為了產生全域唯一和有序遞增的數字序列,常用於主鍵列、唯一索引列等值的產生。
基本概念
瞭解以下概念,將協助您更好地選用Sequence類型:
- 連續:如果本次取值為n,下一次取值一定是n + 1,則是連續的;如果下一次取值不能保證為n + 1,則是非連續的;
- 單調遞增:如果本次取值為n,下一次取值一定是一個比n大的數,則是單調遞增的;
- 單點:存在單點故障風險;
- 宏觀上單調遞增,微觀上非單調遞增:類似於
1、3、2、4、5、7、6、8、......
這樣的序列,這個序列從宏觀是看是遞增的,微觀上非單調遞增。 - 單元化能力:能夠跨執行個體或跨庫分配全域唯一數字序列。
用法
PolarDB-X 1.0中的Sequence主要有兩類用法:
- 顯式Sequence:通過Sequence DDL文法建立和維護,可以獨立使用;通過
select seq.nextval
擷取序列值,seq
是具體Sequence的名字。 - 隱式Sequence,在為主鍵定義AUTO_INCREMENT後,用於自動填滿主鍵,由PolarDB-X 1.0自動維護。
支援的Sequence類型及其特性
PolarDB-X 1.0目前共支援如下4種Sequence類型:
類型(縮寫) | 全域唯一 | 連續 | 單調遞增 | 同一串連內單調遞增 | 非單點 | 資料類型 | 可讀性 | 單元化能力 |
Group Sequence(GROUP) | 是 | 否 | 否 | 是 | 是 | 所有整型 | 好 | 否 |
單元化 Group Sequence(GROUP) | 是 | 否 | 否 | 是 | 是 | 所有整型 | 好 | 是 |
Time-based Sequence(TIME) | 是 | 否 | 宏觀上單調遞增,微觀上非單調遞增 | 是 | 是 | 僅支援 BIGINT | 差 | 否 |
Simple Sequence(SIMPLE) | 是 | 是 | 是 | 是 | 否 | 所有整型 | 好 | 否 |
Group Sequence(GROUP,預設使用)
全域唯一的Sequence,產生的值是自然數序列,但是不保證連續和單調遞增。如果未指定Sequence類型,PolarDB-X 1.0預設使用Group Sequence。
實現原理:採用多個節點產生值來保證高可用,每次取出一段值,如果該段值沒有取完(比如串連斷掉等情形),就會產生跳躍段。
- 優點:全域唯一,不會產生單點問題,效能非常好。
- 缺點:產生的序列不連續,可能會有跳躍段;不會嚴格從起始值開始取值;不能迴圈。
單元化 Group Sequence(GROUP)
以Group Sequence為基礎,擴充了單元化能力,能夠跨執行個體或跨庫實現全域唯一,但同樣不保證連續和單調自增。當單元化 Group Sequence僅配置一個單元時,等價於普通的Group Sequence。
- 優點:具備Group Sequence的所有優點,且擴充了單元化能力。
- 缺點:產生的序列不連續,可能會有跳躍段;不會嚴格從起始值開始取值;不能迴圈。
基本原理與Group Sequence相同;通過擴充參數選項,支援自訂單元數量和單元索引:
- 單元數量決定了單元化 Group Sequence的全域唯一數字序列分配空間;
- 每個單元(由單元索引指定)佔用全域唯一數字序列分配空間中的一個子集;
- 不同單元(指定了不同的單元索引)佔用的子集之間不重疊(即不會分配相同的Sequence值);
- 屬於同一個全域唯一數字序列分配空間的每個單元化Group Sequence,必須指定相同的單元數量和不同的單元索引。
- V5.2:V5.2.7-1606682(2018.4.27)
- V5.3:V5.3.3-1670435(2018.8.15)
Time-based Sequence(TIME)
基於時間戳記+節點編號+序號組合而成的一種Sequence,保證全域唯一和宏觀自增;這種Sequence值的更新不依賴於資料庫,也不需要持久化到資料庫,僅在資料庫中保留名稱和類型資訊,效能很好;產生的是類似於776668092129345536、776668098018148352、776668111578333184、776668114812141568、......
這樣的序列值。
- 優點:全域唯一、效能很好。
- 缺點:產生的序列不連續,起始值、步長、最大值、是否迴圈這些參數對於Time-based Sequence無意義。
- 用於表中自增列時,必須使用BIGINT類型;
- Time-based Sequence從以下版本開始提供支援:
- V5.2:V5.2.8-15432885(2018.11.27)
- V5.3:V5.3.6-15439241(2018.11.29)
僅Simple Sequence支援自訂步長、最大值和迴圈/非迴圈利用。
- 優點:全域唯一、連續、單調遞增,並具備最大值和迴圈利用等特性。
- 缺點:單點,效能較差,存在瓶頸,需要謹慎使用。
每產生一個值都要進行一次持久化操作。
使用情境
這幾種Sequence都保證全域唯一,均可以應用在主鍵列和唯一索引列。
- 大部分情境下建議選用Group Sequence;
- 如果有跨執行個體或跨庫分配全域唯一數字序列的需求,可以選用單元化Group Sequence;
- 如果業務上能接受整體趨勢上的宏觀自增,不介意微觀上的不保證自增,且不想依賴資料庫的分配機制,則Time-based Sequence可能是合適的選擇;
- 如果業務強依賴連續的Sequence值,此時只能使用Simple Sequence(注意Simple Sequence的效能問題)。
以建立一個起始值是100000,步長為1的Sequence為例說明。
- 如果採用 Simple Sequence,則會嚴格產生
100000、100001、100002、100003、100004、.....、200000、200001、200002、200003、......
這樣的序列(全域唯一、連續、單調遞增)。Simple Sequence 會保證持久化,即使發生單點問題,服務重啟後依然會在斷點繼續產生 Sequence 值,中間不會產生跳躍段。Simple Sequence 的機理是每產生一個值都要進行一次持久化操作,因此效能並不是很好。 - 如果採用Group Sequence或單元化 Group Sequence,產生的序列有可能是
200001、200002、200003、200004、100001、100002、100003、......
這樣的序列。
- Group Sequence起始值並不會嚴格從設定的參數(本例中是100000)開始,但保證比該參數大。本例中是從200001開始取值的。
- Group Sequence保證全域唯一,但是會有跳躍段。比如 Group Sequence的某個節點失效,或者某個串連只取了一部分值,然後該串連被關閉了,都會產生跳躍段。該例中200004和100001之間產生了跳躍段。
- 單元化Group Sequence跨執行個體或跨庫的全域唯一性,必須通過指定相同的單元數量和不同的單元索引來保證。