样仍然继续建议通过应用程序来解决。
如何解决?解决的思路大体上和跨节点Join 的解决类似,但是有一点和跨节点Join
不太一样,Join 很多时候都有一个驱动与被驱动的关系,所以Join 本身涉及到的多个表
之间的数据读取一般都会存在一个顺序关系。但是排序分页就不太一样了,排序分页的数据
源基本上可以说是一个表(或者一个结果集),本身并不存在一个顺序关系,所以在从多个
数据源取数据的过程是完全可以并行的。这样,排序分页数据的取数效率我们可以做的比跨
库Join 更高,所以带来的性能损失相对的要更小,在有些情况下可能比在原来未进行数据
切分的数据库中效率更高了。当然,不论是跨节点Join 还是跨节点排序分页,都会使我们
的应用服务器消耗更多的资源,尤其是内存资源,因为我们在读取访问以及合并结果集的这
个过程需要比原来处理更多的数据。
分析到这里,可能很多朋友会发现,上面所有的这些问题,我给出的建议基本上都是通过应用程序来解决。大家可能心里开始犯嘀咕了,是不是因为我是DBA,所以就很多事情都扔给应用架构师和开发人员了?
其实完全不是这样,首先应用程序由于其特殊性,可以非常容易做到很好的扩展性,但
是数据库就不一样,必须借助很多其他的方式才能做到扩展,而且在这个扩展过程中,很难
避免带来有些原来在集中式数据库中可以解决但被切分开成一个数据库集群之后就成为一
个难题的情况。要想让系统整体得到最大限度的扩展,我们只能让应用程序做更多的事情,
来解决数据库集群无法较好解决的问题。
5.4 小结:
通过数据切分技术将一个大的MySQL Server 切分成多个小的MySQL Server,既解决
了写入性能瓶颈问题,同时也再一次提升了整个数据库集群的扩展性。不论是通过垂直切分,
还是水平切分,都能够让系统遇到瓶颈的可能性更小。尤其是当我们使用垂直和水平相结合
的切分方法之后,理论上将不会再遇到扩展瓶颈了。
?
6,案例演示
6.1 创建数据库3个实例
创建多实例参加:http://blog.csdn.net/mchdba/article/details/45798139
6.2 创建库和表以及用户
创建库表
create database `hwdb` /*!40100 default characterset utf8 */;
create table uc_user(user_id bigint primarykey, uc_name varchar(200), created_time datetime) engine=innodb charset utf8;
创建用户
grant insert,update,delete,select on hwdb.*to tim@'192.168.%' identified by 'timgood2013';
执行过程:
mysql> create table uc_user(user_idbigint primary key, uc_name varchar(200), created_time datetime) engine=innodbcharset utf8; Query OK, 0 rows affected (0.53 sec) mysql> mysql> grant insert,update,delete,selecton hwdb.* to tim@'192.168.%' identified by 'timgood2013'; Query OK, 0 rows affected (0.03 sec) mysql>
?
6.3 创建java代码示例
package mysql; import java.math.BigInteger; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Calendar; public classMySQLTest { public static void main(String[] args) { MySQLTestmt=newMySQLTest(); // BigIntegerbi = newBigInteger("2015053010401005"); Stringport=mt.getDBPort(bi.longValue()); Connection conn=mt.getConn(port); mt.insert(conn,bi, "tim--"+bi.longValue()); } // 获取要访问的db端口 public String getDBPort(long user_id){ Stringport="3307"; long v_cast=user_id%3; if (v_cast==1 ){ port="3308"; }else if(v_cast==2){ port="3309"; }else { port="3307"; } return port; } // 获取数据库的连接,如果扩展的话,可以单独做一个接口提供给程序员来调用它 public ConnectiongetConn(String port ) { Connectionconn = null; try { Class.forName("com.mysql.jdbc.Driver"); }catch(ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Stringurl = "jdbc:mysql://192.168.52.130:"+port+"/hwdb"; try { conn= DriverManager.getConnection(url, "tim", "timgood2013"); }catch(SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("the current db is :"+url); return conn; } // 获取日期字符串 public StringgetTimeByCalendar(){ Calendar cal = Calendar.getInstance(); int year = cal.get(Calendar.YEAR);//获取年份 int month=cal.get(Calendar.MONTH);//获取月份 int day=cal.get(Calendar.DATE);//获取日 int hour=cal.get(Calendar.HOUR);//小时 int minute=cal.get(Calendar.MINUTE);//分 int second=cal.get(Calendar.SECOND);//秒 String strdate=year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second; return strdate; } // 开始录入数据 public int insert(Connectioncnn,BigInteger user_id,Str