zoukankan      html  css  js  c++  java
  • 分布式数据库主键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自增。。。

  • 相关阅读:
    PHP安全
    使用 jQuery 简化 Ajax 开发
    我的云之旅–HBase调试(139)
    Java的性能调优
    libsqlite3.dylib与libsqlite3.0.dylib区别
    zookeeper code
    最近的一个框架
    我的云之旅–Lucene内容存储进入Hadoop(136)
    Linux源码阅读推荐阅读图书
    我的云之旅–HMaster启动说明(140)
  • 原文地址:https://www.cnblogs.com/JAYIT/p/5018156.html
Copyright © 2011-2022 走看看