mysql分區(qū)分庫(kù)常用技術(shù)sharding-jdbc和mycat的區(qū)別

一、Mycat和Sharding-jdbc的區(qū)別

1)mycat是一個(gè)中間件的第三方應(yīng)用,sharding-jdbc是一個(gè)jar包

2)使用mycat時(shí)不需要改代碼,而使用sharding-jdbc時(shí)需要修改代碼

Mycat(proxy中間件層):

Sharding-jdbc(TDDL為代表的應(yīng)用層):

二、Mycat分片join

在前面的文章Mysql系列四:數(shù)據(jù)庫(kù)分庫(kù)分表基礎(chǔ)理論中,已經(jīng)說(shuō)過(guò)分庫(kù)分表需要應(yīng)對(duì)的技術(shù)難題有如下幾個(gè):

1.)分布式全局唯一id

2.)分片規(guī)則和策略

3.)跨分片技術(shù)問(wèn)題

4.)跨分片事物問(wèn)題

下面我們來(lái)看一下Mycat是如何解決跨分片技術(shù)問(wèn)題——分片join的

1. 使用全局表方式解決跨分片join問(wèn)題

1.1 先在server.xml里面全局表一致性檢測(cè)

<property name="useGlobleTableCheck">1</property><!-- 1為開(kāi)啟全局表一致性檢測(cè)、0為關(guān)閉 -->

1.2 在schema.xml里面配置全局表

<table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3"/>

全局表說(shuō)明:

1)全局表的插入、更新操作會(huì)實(shí)時(shí)在所有節(jié)點(diǎn)上執(zhí)行,保持各個(gè)分片數(shù)據(jù)的一致性

2)全局表的查詢(xún)操作只從一個(gè)節(jié)點(diǎn)上獲取

3)全局表可以跟任何一個(gè)表進(jìn)行join操作

2. 使用Share Join方式解決跨分片join問(wèn)題

Share Join是一個(gè)簡(jiǎn)單的跨分片join,基于HBT(Human Brain Tech)的方式實(shí)現(xiàn)。

原理:解析SQL語(yǔ)句,拆分成單表的SQL語(yǔ)句執(zhí)行,然后把各個(gè)節(jié)點(diǎn)的數(shù)據(jù)匯集。

示例:

/*!mycat:catlet=io.mycat.catlets.ShareJoin*/select*fromemployee a, employee_detail bwherea.id=b.id;

說(shuō)明:目前只支持兩張分片表的Join,如果要支持多張表需要自己改造程序代碼或者改造Mycat的源代碼

對(duì)應(yīng)Mycat源碼:

io.mycat.catlets.ShareJoin

io.mycat.catlets.Catlet

public class ShareJoin implements Catlet

3. 使用ER Join方式解決跨分片join問(wèn)題

ER表也叫父子表,子表存儲(chǔ)在哪個(gè)分片上依賴(lài)于父表的存儲(chǔ)位置,并且和父表存儲(chǔ)同一個(gè)分片上,即子表的記錄與所關(guān)聯(lián)的父表記錄存放在同一個(gè)數(shù)據(jù)分片上,從而解決跨庫(kù)join的問(wèn)題

在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>

說(shuō)明:

childTable:標(biāo)簽用來(lái)聲明子表:

joinKey:聲明子表的那個(gè)字段和父表關(guān)聯(lián)

parentKey:聲明父表的關(guān)聯(lián)主鍵

primaryKey:父表自身的主鍵

三、Mycat分頁(yè)中的坑

Mycat分頁(yè)的大坑一定要注意:

在對(duì)應(yīng)的分片上去查詢(xún)分頁(yè)數(shù)據(jù)的時(shí)候是從第一條記錄開(kāi)始掃描,然后再取出對(duì)應(yīng)的分頁(yè)數(shù)據(jù),如

SELECT*FROMcustomerORDERBYid LIMIT1000100,100;

這個(gè)sql語(yǔ)句被Mycat轉(zhuǎn)化后

1->dn1{SELECT*FROMcustomerORDERBYid LIMIT0,1000100}2->dn2{SELECT*FROMcustomerORDERBYid LIMIT0,1000100}

所以要在Mycat的server.xm里面開(kāi)啟使用非堆內(nèi)存。否則內(nèi)存會(huì)爆掉

<property name="useOffHeapForMerge">1</property>

優(yōu)化:

1)先查出id

SELECTidFROMcustomerORDERBYid LIMIT1000100,100;

這個(gè)sql語(yǔ)句被mycat轉(zhuǎn)化后

1->dn1{SELECTidFROMcustomerORDERBYid LIMIT0,1000100}2->dn2{SELECTidFROMcustomerORDERBYid LIMIT0,1000100}

2) 拿到所有的id以后再取獲取需要的數(shù)據(jù)

SELECT*FROMcustomerwhereidin(1,2,3....);

這個(gè)sql語(yǔ)句被mycat轉(zhuǎn)化后

1->dn1{SELECT*FROMcustomerwhereidin(1,2,3....);}2->dn2{SELECT*FROMcustomerwhereidin(1,2,3....);}

四、Mycat注解

1. Mycat不支持的SQL語(yǔ)句:

1)? 某些SQL語(yǔ)法,如insert into......select.....

2)? 跨庫(kù)關(guān)聯(lián)查詢(xún)

3)存儲(chǔ)過(guò)程創(chuàng)建

4)存儲(chǔ)過(guò)程調(diào)用

所以Mycat提供Mycat注解來(lái)解決上面這些不支持的SQL語(yǔ)句

Mycat的解決辦法:Mycat注解

語(yǔ)法:

/*!mycat:sql=Mycat注解SQL語(yǔ)句*/真正執(zhí)行的SQL!號(hào)方式

/*#mycat:sql=Mycat注解SQL語(yǔ)句*/真正執(zhí)行的SQL?#號(hào)方式

/**mycat:sql=Mycat注解SQL語(yǔ)句*/真正執(zhí)行的SQL*號(hào)方式

原理:

使用mycat不支持的SQL替換mycat支持的SQL,運(yùn)行Mycat不支持的SQL

Mycat注解規(guī)范:

1) 注解SQL使用select語(yǔ)句,不允許使用delete/update/insert等語(yǔ)句;雖然delete/update/insert等語(yǔ)句也能用在注解中,但這些語(yǔ)句在Sql處理中有額外的邏輯判斷,從性能考慮,請(qǐng)使用select語(yǔ)句。

2) 注解SQL禁用表關(guān)聯(lián)語(yǔ)句。

3) 注解SQL盡量用最簡(jiǎn)單的SQL語(yǔ)句,如select id from tab_a where id=’10000’(如果必要,最好能在注解中指定分片)

4) 無(wú)論是原始SQL 還是注解SQL,禁止DDL語(yǔ)句

5) 能不用注解的盡量不用

2. Mycat注解解決不支持insert into......select.....

/*!mycat:sql=select 1*/insertintotravelrecord(id,user_id,traveldate,fee,days)select3,'Tom','20180826',100,8;

3. Mycat注解創(chuàng)建表

/*!mycat:sql=select 1 from test */createtabletest2(idint);

4. Mycat注解創(chuàng)建存儲(chǔ)過(guò)程

/*!mycat:sql=select 1 from test */createprocedure'test_proc()'beginend;

5. Mycat注解調(diào)用存儲(chǔ)過(guò)程

/*!mycat:sql=select * from user where id=1 */call test_proc();

6. Mycat注解讀寫(xiě)分離數(shù)據(jù)源選擇

/*!mycat:db_type=master */select*from travelrecord;(強(qiáng)制走主庫(kù))/*!mycat:db_type=slave */select*fromtravelrecord;(強(qiáng)制走從庫(kù))

五、Catlet使用

通過(guò)Catlet支持跨分片復(fù)雜SQL實(shí)現(xiàn)以及存儲(chǔ)過(guò)程支持等等

使用方式:通過(guò)mycat注解方式來(lái)執(zhí)行

1. 跨分片聯(lián)合查詢(xún)注解支持

/*!mycat:catlet=io.mycat.catlets.ShareJoin */selecto.id,u.*fromordero,useruwhereo.user_id=u.id;

2. 批量插入與ID自增長(zhǎng)結(jié)合的支持

/*!mycat:catlet=io.mycat.route.sequence.BatchInsertSequence */insertintouser(name)values('Tom'),('Cat'),('Alan');


sharhing-jdbc的用法請(qǐng)參考下面的博客:

https://blog.csdn.net/forezp/article/details/94174114

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容