MyCat分庫分表

垂直拆分原則

  • 儘量保證存在存在關聯的表放到同一個庫中
  • 列如:存在以下數據庫表,我們可以把客戶相關的表分到另外一個庫
#客戶表 rows:20萬
CREATE TABLE customer(
id INT AUTO_INCREMENT,
NAME VARCHAR(200),
PRIMARY KEY(id)
);
#訂單表 rows:600萬
CREATE TABLE orders(
id INT AUTO_INCREMENT,
order_type INT,
customer_id INT,
amount DECIMAL(10,2),
PRIMARY KEY(id)
);
#訂單詳細表 rows:600萬
CREATE TABLE orders_detail(
id INT AUTO_INCREMENT,
detail VARCHAR(2000),
order_id INT,
PRIMARY KEY(id)
);
#訂單狀態字典表 rows:20
CREATE TABLE dict_order_type(
id INT AUTO_INCREMENT,
order_type VARCHAR(200),
PRIMARY KEY(id)
);
  • 此時datahost的配置如下,此處就實現了分庫的目的
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
    <table name="customer" dataNode="dn2" ></table>
</schema>

<dataNode name="dn1" dataHost="host1" database="orders" />
<dataNode name="dn2" dataHost="host2" database="orders" />

<dataHost name="host1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <!-- can have multi write hosts -->
    <writeHost host="hostM1" url="192.168.140.128:3306" user="root"
    password="123123">
    </writeHost>
</dataHost>

<dataHost name="host2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <!-- can have multi write hosts -->
    <writeHost host="hostM2" url="192.168.140.127:3306" user="root"
    password="123123">
    </writeHost>
</dataHost>

實現分表

  • 分表實際上涉及到根據什麼字段拆分,如可以根據id取模主機數(DN)
  • 具體配置
  • schema
<table name="orders" dataNode="dn1,dn2" rule="mod_rule" ></table>
  • rule
<tableRule name="mod_rule">
    <rule>
            <columns>customer_id</columns>
            <algorithm>mod-long</algorithm>
    </rule>
</tableRule>

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
            <!-- how many data nodes -->
            <property name="count">2</property>
</function>

分表後如何實現join?

假設現在有兩張表(order, order_detail)和兩臺host;order進行了分表分別在host1>dn1以及host2>dn1;而order_detail只在host1>dn1

現在order和order_detail進行關聯查詢,mycat解析語句發現order分了表就把sql發送到host1和host2,但是host2上沒有detail表這時,host1返回數據 + host2返回報錯 => 用戶得到報錯

  • 上面的情況一個很自然的想法就是order表怎麼劃分的那麼order_detail就怎麼劃分,具體實現就是所說的ER表,可以把Order表看成父表,order_detail看成訂單詳情表

ER劃分表

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

<table name="orders" dataNode="dn1,dn2" rule="mod_rule" >
    <childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
</table>

全局表

  • 上面的列子中我們可以看到所有的表都需要字典表,並且字典表的數據很小;這時候就可以用全局表;其中考慮到字典表具有以下幾個特性:
    ① 變動不頻繁
    ② 數據量總體變化不大
    ③ 數據規模不大,很少有超過數十萬條記錄
    鑑於此,Mycat 定義了一種特殊的表,稱之爲“全局表”,全局表具有以下特性:
    ① 全局表的插入、更新操作會實時在所有節點上執行,保持各個分片的數據一致性
    ② 全局表的查詢操作,只從一個節點獲取
    ③ 全局表可以跟任何一個表進行 JOIN 操作
<table name="dict_order_type" dataNode="dn1,dn2" type="global" ></table>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章