分布式數據庫部署主要分為兩種,一種是讀寫分離。這個需要弄主從數據庫。主要是寫的時候寫主數據庫,讀的時候讀從數據庫。分散讀取壓力,對於讀多寫少的系統有利於
提高其性能。還有一種是分布式存儲,這種主要是將一張表拆分成多張分表部署到各個服務器中,主要針對寫操作頻繁的系統,如微博,淘寶的訂單系統。
這兩種方案都會遇到主鍵類型及生成方式的問題,還有主從數據庫不同步和主鍵沖突問題。
主鍵類型主要有GUID和數字類型,這里我們不討論GUID;
數字主鍵主要存在唯一性、可同步性兩個方面的不足
可同步性:可以不使用主鍵自增方案。
唯一性:可以單獨使用存儲過程生成ID,設置主鍵ID的初始值步長和最大值,及所對應的表,當然主從數據庫的主表和分表初始值和最大值是不一樣的,一樣的話會造成主鍵重復。
存儲過程:
-- ---------------------------- -- Procedure structure for getId -- ---------------------------- DROP PROCEDURE IF EXISTS `getId`; DELIMITER ;; CREATE DEFINER=`sawyer`@`%` PROCEDURE `getId`(OUT aId INT, OUT aIdEnd INT, aType TINYINT) BEGIN DECLARE id,eid,iStep INT; DECLARE rev TINYINT; SELECT Current_ID,END,Step,REVERSE INTO id,eid,iStep,rev FROM t_id WHERE TYPE=aType; IF id<eid THEN SET aId = id; IF id+iStep >= eid THEN SET aIdEnd = eid; IF rev = 1 THEN UPDATE t_id SET Current_ID=Start_ID WHERE TYPE=aType; ELSE UPDATE t_id SET Current_ID=eid WHERE TYPE=aType; END IF; ELSE SET aIdEnd = id+iStep; UPDATE t_id SET Current_ID=aIdEnd WHERE TYPE=aType; END IF; ELSE SET aId = 0, aIdEnd = 0; END IF; END ;; DELIMITER ;
主表

從表

寫一個java類去調用這個存儲過程生成主鍵。
/* */ package btir.dao.jdbc;
/* */
/* */ import btir.BtirException;
/* */ import btir.dao.ha.DBMgr;
/* */ import btir.dao.ha.PooledStmt;
/* */ import btir.utils.MiscUtil;
/* */ import org.apache.commons.logging.Log;
/* */ import org.apache.commons.logging.LogFactory;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public class IdHolder
/* */ {
/* */ public static final int NO_ID_AVAILABLE = 0;
/* 19 */ private static final Log log = LogFactory.getLog(IdHolder.class);
/* */
/* */
/* */
/* */ private int current;
/* */
/* */
/* */ private int end;
/* */
/* */
/* */
/* */ public synchronized int getId(byte type, int stmtId)
/* */ {
/* 32 */ if (end <= current)
/* */ {
/* */ try
/* */ {
/* 36 */ PooledStmt stmt = DBMgr.borrowSingleStmt(stmtId);
/* */
/* */
/* 39 */ stmt.setByte(3, type);
/* 40 */ stmt.executeUpdate();
/* 41 */ current = stmt.getInt(1);
/* 42 */ end = stmt.getInt(2);
/* 43 */ stmt.returnMe();
/* */ } catch (BtirException e) {
/* 45 */ current = (end = 0);
/* 46 */ log.error("can't get id for type=" + type);
/* 47 */ log.error(MiscUtil.traceInfo(e));
/* 48 */ return 0;
/* */ }
/* 50 */ if (end <= current)
/* 51 */ return 0;
/* */ }
/* 53 */ return current++;
/* */ }
/* */
/* */ public synchronized int getId(byte type, PooledStmt stmt) {
/* 57 */ if (end <= current) {
/* */ try {
/* 59 */ stmt.setByte(3, type);
/* 60 */ stmt.executeUpdate();
/* 61 */ current = stmt.getInt(1);
/* 62 */ end = stmt.getInt(2);
/* */ } catch (BtirException e) {
/* 64 */ current = (end = 0);
/* 65 */ return 0;
/* */ }
/* 67 */ if (end <= current)
/* 68 */ return 0;
/* */ }
/* 70 */ return current++;
/* */ }
/* */ }
上面這段代碼主要是調用存儲過程,對應配置的表的ID自增。。。
