MySQL 垂直切分(讀書筆記整理)
1,垂直分割
相對於水平分割來說,垂直分割比較容易實現一些,垂直分割的意思是把資料庫中不同的業務資料拆分到不同的資料庫中。垂直分割能很好的起到分散資料庫壓力的作用。業務模組不明晰,耦合(表關聯)度比較高的系統不適合使用這種拆分方式。
有得使用者查詢積分快,有的使用者查詢自己的訂單很快,但是查詢自己的使用者資訊很慢,為什嗎?
2,垂直切分的優點
◆ 資料庫的拆分簡單明了,拆分規則明確;
◆ 應用程式模組清晰明確,整合容易;
◆ 資料維護方便易行,容易定位;
3,垂直切分的缺點
◆ 部分表關聯無法在資料庫層級完成,需要在程式中完成;
◆ 對於訪問極其頻繁且資料量超大的表仍然存在效能平靜,不一定能滿足要求;
◆ 交易處理相對更為複雜;
◆ 切分達到一定程度之後,擴充性會遇到限制;
◆ 過讀切分可能會帶來系統過渡複雜而難以維護。
針對於垂直切分可能遇到資料切分及事務問題,在資料庫層面實在是很難找到一個較好的處理方案。實際應用案例中,資料庫的垂直切分大多是與應用系統的模組相對應,同一個模組的資料來源存放於同一個資料庫中,可以解決模組內部的資料關聯問題。而模組與模組之間,則通過應用程式以服務介面方式來相互提供所需要的資料。雖然這樣做在資料庫的總體操作次數方面確實會有所增加,但是在系統整體擴充性以及架構模組化方面,都是有益的。
可能在某些操作的單次回應時間會稍有增加,但是系統的整體效能很可能反而會有一定的提升。而擴充瓶頸問題。
4,拆分規則
根據模組拆分,比如使用者模組、訂單模組、日誌模組,系統參數模組
使用者模組的表:uc_user表;uc_user_info表;uc_action表;uc_profile表
訂單模組表:order_action表;order_list表;shop表;order表;
日誌模組:order_log表;uc_log表;plocc_log表;
系統參數模組:plocc_parameter表;
模組模組之間都一看都是有聯絡的,這些都是用到使用者的,那麼都和使用者模組有關聯
如所示:
5,垂直分割示範5.1準備mysql環境
建立多執行個體參考:
建庫sql語句:
--1 使用者模組 3307連接埠資料庫 create database user_db; CREATE TABLE user_db.`uc_user` ( `user_id` bigint(20) NOT NULL, `uc_name` varchar(200) DEFAULT NULL, `created_time` datetime DEFAULT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; grant insert,update,delete,select on user_db.* to tim@'192.168.%' identified by 'timgood2013';-- 查詢 mysql --socket=/usr/local/mysql3307/mysql.sock -e "select * from user_db.uc_user;";--2 訂單模組 3308連接埠資料庫 create database order_db; CREATE TABLE order_db.`order` ( `order_id` bigint(20) NOT NULL, `shop_id` varchar(200) DEFAULT NULL, `created_time` datetime DEFAULT NULL, `user_id` bigint(20) not null, PRIMARY KEY (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; grant insert,update,delete,select on order_db.* to tim@'192.168.%' identified by 'timgood2013';-- 查詢 mysql --socket=/usr/local/mysql3308/mysql.sock -e "select * from order_db.order;";--3 日誌模組 3309連接埠資料庫 create database log_db; CREATE TABLE log_db.`order_log` ( `orlog_id` bigint(20) NOT NULL, `order_id` varchar(200) DEFAULT NULL, `created_time` datetime DEFAULT NULL, `user_id` bigint(20) not null, `action` varchar(2000) not null, PRIMARY KEY (`orlog_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; grant insert,update,delete,select on log_db.* to tim@'192.168.%' identified by 'timgood2013';-- 查詢 mysql --socket=/usr/local/mysql3309/mysql.sock -e "select * from log_db.order_log;";--4 參數模組 33310連接埠資料庫 create database plocc_db; CREATE TABLE plocc_db.`plocc_parameter` ( `plocc_id` bigint(20) NOT NULL, `pname` varchar(200) DEFAULT NULL, `created_time` datetime DEFAULT NULL, `status` bigint(20) not null, `creator` bigint not null, PRIMARY KEY (`plocc_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; grant insert,update,delete,select on plocc_db.* to tim@'192.168.%' identified by 'timgood2013';--
5.2 示範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.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;public class MySQLTest2 { public static long user_id; public static void main(String[] args) { MySQLTest2 mt=new MySQLTest2(); /* 錄入使用者資料 BigInteger user_id0 = new BigInteger("10001"); Connection conn=mt.getConn("user_db"); mt.insertUser(conn, bi, "tim--"+user_id0.longValue()); */ /* 錄入日誌資料 Connection conn2=mt.getConn("log_db"); BigInteger user_id = new BigInteger("10001"); BigInteger order_id = new BigInteger("20150531001"); BigInteger orlog_id = new BigInteger("20150531001"); mt.insertLog(conn2, user_id,order_id , orlog_id, "create a order for tim"); */ //錄入訂單資料 Connection conn3=mt.getConn("order_db"); BigInteger user_id2 = new BigInteger("10001"); BigInteger order_id2 = new BigInteger("20150531001"); BigInteger shop_id2 = new BigInteger("20150531001"); mt.insertOrder(conn3,order_id2 , shop_id2, user_id2); } // 擷取資料庫的串連,如果擴充的話,可以單獨做一個介面提供給程式員來調用它 // String type:串連的資料類型 public Connection getConn(String type ) { String port="3307"; if (type=="user_db" ){ port="3307"; }else if(type=="order_db"){ port="3308"; }else if(type=="log_db"){ port="3309"; }else if(type=="plocc_db") { port="3310"; }else{ port="3311"; } Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } String url = "jdbc:mysql://192.168.52.130:"+port+"/"+type; 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 String getTimeByCalendar(){ /* 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; */ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設定日期格式 System.out.println(df.format(new Date()));// new Date()為擷取當前系統時間 return df.format(new Date()); } // 開始錄入使用者資料 public int insertUser(Connection cnn,BigInteger user_id,String name){ String sql="insert into user_db.uc_user(user_id,uc_name,created_time)values(?,?,?)"; int i=0; long uid = user_id.longValue(); Connection conn=cnn; try{ PreparedStatement preStmt =conn.prepareStatement(sql); preStmt.setLong(1, uid); preStmt.setString(2,name); preStmt.setString(3,getTimeByCalendar()); i=preStmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } return i;//返回影響的行數,1為執行成功 } // 開始錄入日誌資料 public int insertLog(Connection cnn,BigInteger user_id,BigInteger order_id,BigInteger orlog_id,String action){ String sql="insert into log_db.order_log(orlog_id,order_id,created_time,user_id,action)values(?,?,?,?,?)"; int i=0; Connection conn=cnn; try{ PreparedStatement preStmt =conn.prepareStatement(sql); preStmt.setLong(1, user_id.longValue()); preStmt.setLong(2, order_id.longValue()); preStmt.setString(3,getTimeByCalendar()); preStmt.setLong(4, orlog_id.longValue()); preStmt.setString(5,action); i=preStmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } return i;//返回影響的行數,1為執行成功 } // 開始錄入訂單資料 public int insertOrder(Connection cnn,BigInteger order_id,BigInteger shop_id,BigInteger user_id){ String sql="insert into order_db.order(order_id,shop_id,created_time,user_id)values(?,?,?,?)"; int i=0; Connection conn=cnn; try{ PreparedStatement preStmt =conn.prepareStatement(sql); preStmt.setLong(1, order_id.longValue()); preStmt.setLong(2, shop_id.longValue()); preStmt.setString(3,getTimeByCalendar()); preStmt.setLong(4, user_id.longValue()); i=preStmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } return i;//返回影響的行數,1為執行成功 } //開始錄入參數資料 public int insertPlocc(){ int i=0; return i; }}
更多詳情見請繼續閱讀下一頁的精彩內容: