零:開篇
目錄
Mycat 的分片 join,只支持分庫表的 join(多庫同名表),單庫多表既 table 標籤的 subtables 屬性不支持 join 操作,會直接報錯。
一:常見的 join 類型
INNER JOIN 內連接:也叫等值連接,inner join 產生同時符合 A 表和 B 表的一組數據。既只在笛卡爾積中取交集的數據
LEFT JOIN 左連接:從 A表(左) 產生一套完整的記錄,與匹配的 B表記錄(右表) .如果沒有匹配, 右側將包含 null, 在 MySQL 中 等同於 left outer join。不僅在笛卡爾積中取交集,還保留左表全部數據。
RIGHT JOIN 右連接: 同 Left join , AB 表互換即可。
Cross join 交叉連接:得到的結果是兩個表的乘積,即笛卡爾積。笛卡爾(Descartes)乘積又叫直積。假設集合 A={a,b},集合 B={0,1,2},則兩個集合的笛卡爾積爲 {(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)} 。可以擴展到多個集合的情況。類似的例子有,如果 A 表示某學校學生的集合,B 表示該學校所有課程的集合,則 A 與 B 的笛卡爾積表示所 有可能的選課情況。
Full join 全連接:產生的所有記錄(雙方匹配記錄)在表 A 和表 B。如果沒有匹配,則對面將包含 null。
儘量避免使用 Left join 或 Right join,而用 Inner join。
在使用 Left join 或 Right join 時,ON 會優先執行,where 條件在最後執行,所以在使用過程中,條件儘可能的在 ON 語句中判斷,減少 where 的執行
少用子查詢,而用 join。
MyCat 目前版本支持跨分片的 join,主要實現的方式有四種。
全局表,ER 分片,catletT(人工智能) 和 ShareJoin,ShareJoin 在開發版中支持,前面三種方式 1.3.0.1 支持。
二:全局表實例實操測試
一個真實的業務系統中,往往存在大量的類似 字典表 的表格,它們與業務表之間可能有關係,這種關係,可 以理解爲“標籤”,而不應理解爲通常的“主從關係”,這些表基本上 很少變動,可以根據主鍵 ID 進行緩存。
字典表具有以下幾個特性:
-
變動不頻繁
-
數據量總體變化不大
-
數據規模不大,很少有超過數十萬條記錄。
鑑於此,MyCAT 定義了一種特殊的表,稱之爲“全局表”,全局表具有以下特性:
-
全局表的插入、更新操作會實時在所有節點上執行,保持各個分片的數據一致性
-
全局表的查詢操作,只從一個節點獲取
-
全局表可以跟任何一個表進行 JOIN 操作
類似每個節點都維護一個表,該表的變動會傳播給所有節點。查詢時可以從任意庫中選擇,類似鏡像節點
配置:聲明該表 jointable 爲一個全局表,所屬節點 dn1 dn2
<table name="jointable" primaryKey="id" type="global" autoIncrement="true" dataNode="dn$1-2" />
lsqtable 是之前建立的單表分兩庫的表,配置如下
<table name="lsqtable" primaryKey="id" autoIncrement="true" dataNode="dn$1-2" rule="mod-long" />
查詢語句:
explain SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id
dn1 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id
dn2 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id
如果在 on 語句中確定庫,則只會發送到一個庫中執行
explain SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id AND l.id = 3
dn2 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id AND l.id = 3
全局表的插入操作測試:確定了每個庫中都會插入條數據
EXPLAIN INSERT INTO jointable (id, name) VALUES (2, 'wxf')
dn1 INSERT INTO jointable (id, name) VALUES (2, 'wxf')
dn2 INSERT INTO jointable (id, name) VALUES (2, 'wxf')
MyCat 說 join 操作最多兩個表,嘗試多個全局表 join 的可能性,證明多個全局表不影響 join 操作。
新加一個全局表
<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" />
SELECT * FROM
jointable j INNER JOIN lsqtable l ON j.id = l.id
INNER JOIN otherjointable o ON j.id = o.id
dn1 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id INNER JOIN otherjointable o ON j.id = o.id
dn2 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id INNER JOIN otherjointable o ON j.id = o.id