服务器开发之用户ID生成策略

来源:互联网 发布:正规淘宝小号购买平台 编辑:程序博客网 时间:2024/05/16 15:45

简介

用户id可以理解为用户的唯一标识。

用户id的特点

唯一性

主要表现在这个id不会重复。

ID尽量短,方便记忆

因为id作为用户的唯一标识,它的用途很多,比如身份认证等一系列的操作,都有可能用到,因此需要id尽量短。

有意义

比如,ID中可能会包含一些信息,比如用于标识是通过什么方式注册的。

ID生成服务的基本思路

  • ID生成服务管理多个不同类型的ID池 (pool)。
  • 每种不同类型注册用户的ID属于不同的ID池。
  • 每个ID池由多个定长的id块构成。
  • 每个ID块包含一段连续的ID。
  • 每个ID块并不完全分配,而是按照一个给定的填充率随机选择来分配,比如假设填充率是50%,那么每个 ID 块中只有大约一半的ID会被分配。也就是说每个ID块是有随机空洞的。
  • 如果某个ID块中可用ID被分配完毕,服务会自动生成下一个新的ID块,并按照填充率去掉不可用ID。
  • 将这些生成的可用ID存入ID池中,等待被获取;不可用ID记录到另外的表中。

具体实现

数据库表

-- common标识(usedfor)的uid池CREATE TABLE `uid_common_generator` (  `RANDOM_VALUE` bigint(20) NOT NULL,  `UID` int(11) NOT NULL,  PRIMARY KEY (`RANDOM_VALUE`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- common标识(usedfor)的不可用uid池CREATE TABLE `uid_common_not_available` (  `RANDOM_VALUE` bigint(20) NOT NULL,  `UID` int(11) NOT NULL,  PRIMARY KEY (`RANDOM_VALUE`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- uid生成规则表CREATE TABLE `uid_generate_range` (  `ID` int(11) NOT NULL AUTO_INCREMENT,  `MIN_UID` int(11) NOT NULL,  `MAX_UID` int(11) NOT NULL,  `CREATE_DATE` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  `USING_STATUS` smallint(6) NOT NULL DEFAULT '0',  `USER_FOR` varchar(50) NOT NULL,  PRIMARY KEY (`ID`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;INSERT INTO `uid_generate_range` VALUES ('1', '10000000', '10500000', '2016-10-09 10:31:57', '1', 'common');-- 创建获取uid事务 DROP PROCEDURE IF EXISTS `GET_UID_FOR_REGISTER`;DELIMITER ;;CREATE DEFINER=`root`@`%` PROCEDURE `GET_UID_FOR_REGISTER`(p_used_for varchar(50))BEGIN    declare userUid int default 0;     declare randomValue bigint default 0;    case p_used_for        when 'common' then        start transaction;            select UID, RANDOM_VALUE into userUid, randomValue from UID_COMMON_GENERATOR limit 1 for update;                if userUid > 0 then                    delete from UID_COMMON_GENERATOR where RANDOM_VALUE = randomValue;                end if;        commit;    end case;    select userMid from dual;END;;DELIMITER ;

获取uid

java

/** * 通过uid区间标识(usedfor)得到一个编号。 * @param usedFor * @return */Long getUidForRegister(String usedFor);

mybatis

<select id="getUidForRegister" parameterType="java.lang.String" resultType="java.lang.Long" statementType="CALLABLE">      {call GET_UID_FOR_REGISTER(#{usedFor, mode=IN, jdbcType=VARCHAR})} </select>

总结

用户ID的生成策略有很多,需要结合具体的业务来决定。

0 0
原创粉丝点击