天天看点

分区分表支持

最近,正在做一个互联网项目,数据量比较大,因此,拟采用分区分表支持。

文中也总结了觉的分区分表实现方式有两种: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年结束之前能够放出来。

框架的扩展性非常好,完全可以自定义各种分区,分表,路由规则的实现,当然在一般情况下,框架自带的也已经足够。

相关内容在实现到一定程度再行补充。