枚舉分片適用於「分片鍵取值固定、有限」的業務場景,如按省份、城市、業務類型等固定枚舉值將數據路由到指定分片。MyCat 通過 PartitionByFileMap 讀取映射文件實現該功能。本文完整記錄配置、映射文件、建表、寫入驗證與路由日誌分析。
枚舉值=分片編號(分片編號從 0 開始)。defaultNode。type=0)與字符串型(type=1)兩種模式。<function name="hash-int-mc040301"
class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int04.txt</property>
<property name="defaultNode">0</property>
<property name="type">0</property> <!-- 0=Integer, 1=String -->
</function>
<tablerule name="tr-hash-int-mc040301">
<rule>
<columns>PROVINCE</columns>
<algorithm>hash-int-mc040301</algorithm>
</rule>
</tablerule>
10000=0 # 北京 → 分片 0 (dn21)
10010=1 # 上海 → 分片 1 (dn22)
注意:所有節點配置均從 0 開始編號,0 代表第一個物理節點。
CREATE TABLE ORDER040301(
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
PROVINCE INT,
SN VARCHAR(64),
CREATE_TIME DATETIME
);
-- PROVINCE=10000 → dn21
INSERT INTO ORDER040301(ID,PROVINCE,SN,CREATE_TIME)
VALUES(1,10000,'beijing_10006_10000',NOW());
-- PROVINCE=10010 → dn22
INSERT INTO ORDER040301(ID,PROVINCE,SN,CREATE_TIME)
VALUES(2,10010,'shanghai_10010',NOW());
mysql> EXPLAIN INSERT ... VALUES(1,10000,...);
+-----------+--------------------------------------------------+
| DATA_NODE | SQL |
+-----------+--------------------------------------------------+
| dn21 | INSERT ... VALUES(1,10000,...) |
+-----------+--------------------------------------------------+
mysql> EXPLAIN INSERT ... VALUES(2,10010,...);
+-----------+--------------------------------------------------+
| DATA_NODE | SQL |
+-----------+--------------------------------------------------+
| dn22 | INSERT ... VALUES(2,10010,...) |
+-----------+--------------------------------------------------+
關鍵節點(PROVINCE=10010 寫入):
ServerConnection INSERT ... PROVINCE=10010route={ 1 -> dn22{INSERT ...} } rrsNonBlockingSession release connection MySQLConnection[id=16, host=13.123.1.11, port=3327, attachment=dn22{...}]PhysicalDatasource release channel ... modifiedSQLExecuted=falsemysql> EXPLAIN SELECT * FROM ORDER040301 WHERE PROVINCE=10000;
+-----------+--------------------------------------------------+
| DATA_NODE | SQL |
+-----------+--------------------------------------------------+
| dn21 | SELECT * FROM ORDER040301 WHERE PROVINCE=10000 LIMIT 100 |
+-----------+--------------------------------------------------+
日誌:SQLRouteCache add cache ... route={ 1 -> dn21{...} }
mysql> EXPLAIN SELECT * FROM ORDER040301 WHERE SN='beijing_10006_10000';
+-----------+--------------------------------------------------+
| DATA_NODE | SQL |
+-----------+--------------------------------------------------+
| dn21 | SELECT * FROM ORDER040301 WHERE SN='beijing_10006_10000' LIMIT 100 |
| dn22 | SELECT * FROM ORDER040301 WHERE SN='beijing_10006_10000' LIMIT 100 |
+-----------+--------------------------------------------------+
mysql> EXPLAIN SELECT * FROM ORDER040301 WHERE PROVINCE < 10010;
+-----------+--------------------------------------------------+
| DATA_NODE | SQL |
+-----------+--------------------------------------------------+
| dn21 | SELECT * FROM ORDER040301 WHERE PROVINCE < 10010 LIMIT 100 |
| dn22 | SELECT * FROM ORDER040301 WHERE PROVINCE < 10010 LIMIT 100 |
+-----------+--------------------------------------------------+
即使條件 PROVINCE < 10010 理論上只包含 10000,MyCat 無法從範圍條件推導具體枚舉值,故廣播查詢。
reload @@config,否則新值將走 defaultNode 導致數據傾斜。type=0 要求分片字段與映射文件鍵均為整數;字符串枚舉請改用 type=1。defaultNode 建議指向容量最大的分片,或設置為專門的「異常數據」分片便於排查。