分布式數據庫主鍵id生成策略


分布式數據庫部署主要分為兩種,一種是讀寫分離。這個需要弄主從數據庫。主要是寫的時候寫主數據庫,讀的時候讀從數據庫。分散讀取壓力,對於讀多寫少的系統有利於

提高其性能。還有一種是分布式存儲,這種主要是將一張表拆分成多張分表部署到各個服務器中,主要針對寫操作頻繁的系統,如微博,淘寶的訂單系統。

這兩種方案都會遇到主鍵類型及生成方式的問題,還有主從數據庫不同步和主鍵沖突問題。

主鍵類型主要有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自增。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM