分布式數據庫部署主要分為兩種,一種是讀寫分離。這個需要弄主從數據庫。主要是寫的時候寫主數據庫,讀的時候讀從數據庫。分散讀取壓力,對於讀多寫少的系統有利於
提高其性能。還有一種是分布式存儲,這種主要是將一張表拆分成多張分表部署到各個服務器中,主要針對寫操作頻繁的系統,如微博,淘寶的訂單系統。
這兩種方案都會遇到主鍵類型及生成方式的問題,還有主從數據庫不同步和主鍵沖突問題。
主鍵類型主要有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自增。。。
