主要過程包括:
- 分庫分表的路由定位
- sql語句的 ast 抽象語法樹的解析
- 通過自定義 SQLASTVisitor (MySQLSelectASTVisitor) 遍歷sql ast,解析出邏輯表名
- 查找邏輯表名對應的分庫分表規則
- 根據邏輯表的分庫分表規則,遍歷sql ast定位分片鍵的值 根據中間件的設計需要支持分庫分表語句的各種sql場景,遍歷ast樹,做一堆if else判斷 (分庫分表后,不應該支持復雜的sql,可酌情考慮公司業務場景 需要支持的sql語句 來遍歷 sql樹)
- SqlRewrite#rewrite 改寫 sql語句,根據邏輯表的分庫分表規則和分片鍵的值,將邏輯表名改寫成目標物理表名; 改寫后的sql即為在目標分庫中執行的真實SQL 改寫sql的過程也是利用 SQLASTVisitor 來操作的,不過用的自定義的 ShardRewriteTableOutputVisitor (繼承輸出型visitor:SQLASTOutputVisitor)來遍歷 sql tree 輸出sql字符串, 遇到 SQLExprTableSource 節點的時候改寫表名
- 路由到目標的分庫和分表 可能是多個庫和表, #reWriteAndMergeParams 會把sql參數塞到所有重寫后的的分表sql語句中
- 后面再執行的時候 會根據 路由結果是不是多個分庫,按照配置單庫並發度 concurrencyLevel (默認是1)來決定在每個目標分庫中不同表的sql是用一個java 線程還是多個java線程並行執行, 具體過程 參考 如果定位到多個分庫表怎么執行的?
完整目錄:數據庫中間件zebra源碼分析