天天看點

分區分表支援

最近,正在做一個網際網路項目,資料量比較大,是以,拟采用分區分表支援。

文中也總結了覺的分區分表實作方式有兩種:jdbc層的封裝,orm架構層的實作

tiny架構中拟采用jdbc層的封裝,采用jdbc層的封裝有諸多好處,第一,對應用的影響最小,第二,對各種資料庫有更好的更通用的支援;當然,同步帶來的問題就是難度比較大。

目前拟提供特性如下:

支援同庫分表:即把表aaa,分為aaa0,aaa1,aaa2,aaa3...的方式

支援異庫分表:即把表aaa分解到db0,db1,db2,db3多個schema中的方式

支援讀寫分離方式:即一寫多讀的支援

支援讀寫分離備方式:即一寫,若幹寫備,多讀的方式。如果寫庫當機,備機可以頂上

删除語句示例代碼如下:

<a href="http://my.oschina.net/tinyframework/blog/185134#">?</a>

1

2

3

4

5

<code>class.forname(</code><code>"org.tinygroup.dbcluster.jdbc.tinydriver"</code><code>);</code>

<code>        </code><code>connection conn = drivermanager.getconnection(</code><code>"jdbc:dbcluster://cluster1"</code><code>,</code><code>"sa"</code><code>,</code><code>"123456"</code><code>);</code>

<code>        </code><code>statement stmt = conn.createstatement();</code>

<code>        </code><code>string sql =</code><code>"delete from aaa"</code><code>;</code>

<code>        </code><code>stmt.execute(sql);</code>

日志輸出

<code>using shard:shard0 to execute sql:delete from aaa</code>

<code>using shard:shard1 to execute sql:delete from aaa</code>

<code>using shard:shard2 to execute sql:delete from aaa</code>

插入語句示例:

6

7

8

9

<code>        </code><code>string sql;</code>

<code>        </code><code>//插入100條資料</code>

<code>        </code><code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i &lt;</code><code>100</code><code>; i++) {</code>

<code>            </code><code>sql =</code><code>"insert into aaa(id,aaa) values ("</code> <code>+ clustermanager.getprimarykey(cluster,</code><code>"aaa"</code><code>) +</code><code>",'ppp')"</code><code>;</code>

<code>            </code><code>boolean</code> <code>result = stmt.execute(sql);</code>

<code>        </code><code>}</code>

控制台資訊:

10

11

12

13

14

15

16

17

<code>using shard:shard0 to execute sql:insert into aaa(id,aaa) values (</code><code>0</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard1 to execute sql:insert into aaa(id,aaa) values (</code><code>1</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard2 to execute sql:insert into aaa(id,aaa) values (</code><code>2</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard0 to execute sql:insert into aaa(id,aaa) values (</code><code>3</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard1 to execute sql:insert into aaa(id,aaa) values (</code><code>4</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard2 to execute sql:insert into aaa(id,aaa) values (</code><code>5</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard0 to execute sql:insert into aaa(id,aaa) values (</code><code>6</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard1 to execute sql:insert into aaa(id,aaa) values (</code><code>7</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard2 to execute sql:insert into aaa(id,aaa) values (</code><code>8</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard0 to execute sql:insert into aaa(id,aaa) values (</code><code>9</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard1 to execute sql:insert into aaa(id,aaa) values (</code><code>10</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard2 to execute sql:insert into aaa(id,aaa) values (</code><code>11</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard0 to execute sql:insert into aaa(id,aaa) values (</code><code>12</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard1 to execute sql:insert into aaa(id,aaa) values (</code><code>13</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard2 to execute sql:insert into aaa(id,aaa) values (</code><code>14</code><code>,</code><code>'ppp'</code><code>)</code>

<code>using shard:shard0 to execute sql:insert into aaa(id,aaa) values (</code><code>15</code><code>,</code><code>'ppp'</code><code>)</code>

<code>......</code>

比上面的示例看出,對于最終使用者來說,除了url有些不一樣之外,其它是與普通的jdbc使用完全一緻的。是以,不會像某些架構,隻支援少數幾種資料庫類型的情況出現。隻要是遵從jdbc規範的資料庫,全部可以支援。

當然,說到到分片處理,唯一主鍵的處理就非常關鍵。

為了友善使用,主鍵的處理,是在jdbc層進行處理的,也就是說,隻要像常見的方式設定主鍵自動生成,應用層不用做任何特殊處理,底層就會自動為期提供主鍵,且保證不同的分片之間的主鍵不會重複。

對于sql的支援來說,除了兩個分片之間不能做關聯之外,其它與常見處理沒有任何差別。

當然,為了友善使用,對于統計方面的支援也是非常好的。

比如:執行的sql語句是select count(*) from aaa,底層會自動進行結果搜尋并傳回合并後的結果。

比如:執行的sql語句是select avg(score) from student,底層也會進行處理,并傳回合并後的結果,能夠做到結果與未庫完全一緻。

對于讀寫分離來說,處理就簡單多了,這裡不再細述。

進度情況:目前已經實作相關部分功能,期待在2013年結束之前能夠放出來。

架構的擴充性非常好,完全可以自定義各種分區,分表,路由規則的實作,當然在一般情況下,架構自帶的也已經足夠。

相關内容在實作到一定程度再行補充。