麒麟v10 上部署 TiDB v5.1.2 生产环境优化实践
779
2023-04-03
分布式数据库主键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
主表
从表
写一个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自增。。。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。