版本要求
PolarDB-X版本必須為5.4.18-17047709及以上。
適用情境
在電商情境,業務訂單表常常會出現以下現象:業務訂單表的兩個列或多個列之間的值存在一種協同關係,比如,常見的訂單表的order_id與buyer_id的後N位元字總是相同的。由於業務訂單表的資料量一般偏大,使用者考慮在對訂單表進行水平切分時,能讓訂單表同時按order_id或buyer_id的後N位元字進行水平切分。這樣業務應用在一些下單情境的事務中,應用無論是從order_id=維度讀寫還是buyer_id=?維度進行讀寫,均能路由到同一個物理分區,從而避免出現大量的跨庫事務。
那麼,PolarDB-X的CO_HASH分區策略就是專用來協助業務解決上述情境所碰到的分區問題:
分區表的多個分區列的取值之間存在特殊的協同關係(比如,後N位的數值相同、前N位的資料相同,等等 );
分區表支援同時按多個不同的分區列進行獨立路由(即這些分區列之間沒有首碼關係,查詢單獨帶上各個分區列的等值查詢條件均能進行分區裁剪);
文法
要求PolarDB-X支援同時按多個不同的分區列的不同取值進行路由。
CREATE TABLE ...
PARTITION BY CO_HASH(partition_expr_list)
PARTITIONS number;
partition_expr_list:
partition_expr, partition_expr [, partition_expr, ...]
partition_expr:
partition_column
| partition_func(partition_column)
# 分區函數定義
partition_func:
RIGHT
| LEFT
| SUBSTR
| SUBSTRINGCO_HASH分區策略與HASH/KEY分區策略的主要區別請參見與Hash/Key分區策略的主要區別。
限制
分區列使用分區函數時,不允許嵌套多層的分區函數,例如
SUBSTR(SUBSTR(c1,-6),4)。所有分區列的類型必須完全一致,包括:
分區列類型的charset與collation;
分區列類型的長度定義或精度定義等。
預設最大分區數目不允許超過8192。
預設最大分區列數目不允許超過5個。
分區函數的使用限制:
RIGHT
LEFT
SUBSTR
樣本
假如業務有一張訂單表orders,它的每一行錄的order_id與buyer_id的後6位的數字總是相同的。
那麼,如果使用者想對訂單表orders同時按order_id與buyer_id兩個列的後6位元字進行分區,並期望同一行order_id與buyer_id這兩個列的等值查詢條件均能路由到同一個分區的話,可以使用如下的文法定義:
CREATE TABLE t_orders(
id bigint not null auto_increment,
seller_id bigint,
order_id bigint,
buyer_id bigint,
order_time datetime not null,
primary key(id)
)
PARTITION BY CO_HASH(
RIGHT(`order_id`,6) /*取c1列的後6位字元*/,
RIGHT(`buyer_id`,6) /*取c2列的後6位字元*/
)
PARTITIONS 8;CO_HASH與其它分區函數的用法,請參見分區函數。
相關限制
資料類型限制
整數類型: BIGINT/BIGINT UNSINGEDINT/INT/INT UNSINGED/MEDIUMINT/MEDIUMINT UNSINGED/SMALLINT/SMALLINT UNSINGED/TINYINT/TINYINT UNSINGED
時間類型:DATETIME/DATE/TIMESTAMP
字串類型:CHAR/VARCHR
定點類型:DECIMAL(小數部分的位元要求必須是0)
分區列相關限制
分區列取值的協同關係必須由業務保證,分區表僅校正路由結果。CO_HASH由於多個分區列之間的取值存在著由業務維護的協同的關係。因此,對於CO_HASH分區表的每一行記錄的插入,不同分區列的值的分區路由結果要求必須是一致的。但是,即使同一行的記錄不同的分區列的取值的分區路由結果完全一致,也不一定能保證這些分區列的協同關係不被破壞。因此,分區列之間的協同關係必須由使用者自行保證,PolarDB-X只負責檢驗路由結果,不負責校正資料本身的協同關係,例如:業務定義c1與c2的後4位字元是相同的,現在假如c1=1001234與c2=1320都能路由分區0,那麼inssert (c1,c2) values (100234,1320)是允許的,但此時c1與c2的後4位並不相同。
DML修改分區列限制。由於CO_HASH的多個分區列之間的取值存在協同的關係,為防止資料分布錯誤,PolarDB-X對於DML關於CO_HASH分區列的值的修改。
對於INSERT/REPLCAE語句,VALUES子句中同一行的不同分區列的值在路由計算後,其分區結果若不一致,將被禁止插入並報錯;
對於UPDATE及UPSERT語句,SET子句在修改分區列的取值時,必須要對所有分區列同時進行修改,比如,c1與c2是分區列,那麼應該是UPDATE t1 SET c1='xx',c2='yy' WHERE id=1 。如果SET子句在修改分區列後的值,並且會導致同一行的不同分區列的取值產生不同的分區路由結果的話,該UPDATE語句或UPSERT語句將被禁止並報錯;
如果使用了CO_HASH作為GSI的分區策略,那麼所有對主表的INSERT/UPDATE等操作,若該DML操作會導致主表的GSI表的同一行資料的不同分區列的取值產生不同的分區路由結果,那麼,該DML操作也將被禁止並報錯。
關於整數類型首碼0的說明。CO_HASH的分區列之間的協同關係,所以它的分區列通常需要藉助使用SUBSTR/LEFT/RIGHT等分區函數進行定義。因此,一些整數類型的數字被截取後,容易出現首碼為0的情況。比如,業務定義 c1 與 c2 的後4位字元是相同的,現在假如 c1=1000034 與 c2=34, c1的後4位字元是’0034‘。CO_HASH對於類型是整數類型的分區列,所有原始的數字被截取後,都會統一自動轉為分區列對應的整數類型再進行路由。因此,對於'0034' 的字串,它實際會被轉為整數34 再進行雜湊值計算並路由分區,從而自動處理首碼0。