MyCat Join 專題 ---- ER 分片

ER Join:實體關係(entity relation) join

目錄

ー:MyCat 權威指南

二:ER 分片實操


 

ー:MyCat 權威指南


MyCAT 借鑑了 NewSQL 領域的新秀 Foundation DB 的設計思路,Foundation DB 創新性的提出了 Table Group 的概念,其將子表的存儲位置依賴於主表,並且物理上緊鄰存放,因此徹底解決了 JION 的效率和性能問 題,根據這一思路,提出了基於 E-R 關係 的數據分片策略,子表的記錄與所關聯的父表記錄存放在同一個數據分片上。 

說白了就是將相關聯的數據,需要級聯查詢的數據放進同一個分片中。

customer 採用 sharding-by-intfile 這個分片策略,或者其他的分片策略,分片在 dn1,dn2 上,orders 依賴父表進行分片,兩個 表的關聯關係爲 orders.customer_id = customer.id

既字表是按照父表的分片字段進行分片的,這樣的話,父表數據和字表數據的相關聯的數據都會在同一個數據分片上。跨庫分片 join 變得簡單,子表可以配置多個。且可以進行嵌套查詢。

於是數據分片和存儲的示意圖如下:

這樣一來,分片 Dn1 上的的 customerDn1 上的 orders 就可以進行局部的 JOIN 聯合,Dn2 上也如此,再合 並兩個節點的數據即可完成整體的 JOIN,試想一下,每個分片上 orders 表有 100 萬條,則 10 個分片就有 1 個億,基 於 E-R 映射的數據分片模式,基本上解決了 80% 以上的企業應用所面臨的問題。 配置 以上述例子爲例,schema.xml 中定義如下的分片配置

<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
    <childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
        <childTable name="order_items" joinKey="order_id" parentKey="id" />
    </childTable>
    <childTable name="customer_addr" primaryKey="ID" joinKey="customer_id" parentKey="id" />
</table>

 

二:ER 分片實操


ER Join:不限制查詢的表數,因爲設計的原型就是所有相關聯的數據都在同一個分頁。

查詢:按邏輯來說,子表不需要單獨查詢。或者只是主表的一個數據拓展。

子表單表查詢:因爲是按照主表的分片鍵路由的。所以只有主表的分片鍵查詢條件纔會路由到正確的位置。沒有的話就全庫查找數據集,之後合併多個數據集。

主表 + 子表 join 查詢:有分片鍵的查詢就路由到對應庫。查詢對應的 join 信息,沒有的話就所有的庫進行數據的 join ,之後合併。

限制:經過測試,沒有表數的限制。既一個 table 標籤中的所有表都可以進行 join 操作。此外還可以再與多個 global 全局表進行 join

 

本地測試:

<schema name="mydb" checkSQLschema="true" sqlMaxLimit="100">
    <table name="lsqtable" primaryKey="id" autoIncrement="true" dataNode="dn$1-2" rule="mod-long" >
        <childTable name="lsqtable_supplement" primaryKey="id" joinKey="id" parentKey="id" >
            <childTable name="lsqtable_supplement_items" joinKey="parent_id" parentKey="id" />
        </childTable>
        <childTable name="lsqtable_supplement_other" primaryKey="id" joinKey="id" parentKey="id" />
    </table>
    <table name="jointable" primaryKey="id" type="global" autoIncrement="true" dataNode="dn$1-2" />
    <table name="otherjointable" primaryKey="id" type="global" autoIncrement="true" dataNode="dn$1-2" />
</schema>


<dataNode name="dn1" dataHost="localhost1" database="mydb" />
<dataNode name="dn2" dataHost="localhost2" database="mydb" />

邏輯庫:mydb

邏輯表: 主表 lsqtest

子表補充表 

lsqtable_supplement 

子表補充表明細 

lsqtable_supplement_items 

主表動靜分離子表 

lsqtable_supplement_other

所在數據節點: dn$1-2   dn$1-2   dn$1-2   dn$1-2  
分片鍵:  id   id   parent_id  id 

 

 

 

 

 

全局表: jointable                         otherjointable
所在數據節點: dn$1-2   dn$1-2  

 

 

 

所有子表會默認繼承所屬主表的 分片規則 來保證相關數據都在一個分片區之內。

 

查詢語句:

explain select *
FROM lsqtable_supplement s
LEFT JOIN lsqtable l ON l.id = s.id
LEFT JOIN lsqtable_supplement_other o ON l.id = o.id
LEFT JOIN lsqtable_supplement_items i ON l.id = i.parent_id
INNER JOIN jointable j ON l.id = j.id
INNER JOIN otherjointable oj ON l.id = oj.id

會將查詢語句路由到其他幾個節點,每個節點執行相同語句獲取結果集。之後 MyCat 會合並這些結果集。

該方案只適用於 主表A ---> 子表B ---> 字典表 這種情況

而這種 主表A ---> 關係表AB ---> 主表B  這種情況,兩種主表屬於不同的範疇,所以兩主表插入 關係表AB 的值不保證保存在同一分片上。可以考慮冗餘關係表的方法來保證所有節點相同。但是又不符合全局表的定義。因爲是一種常變的數據。

一般情況下,ER分區全局表 可以滿足大部分的需求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章