数据库使用自增还是uuid,推荐雪花算法
·
自增id:存储空间小,性能高,但在分布式系统,以及多数据库数据交换,会出现问题。
uuid:优点就是保证唯一,本身具有无序性,正式系统推荐使用uuid。
但是因为UUID是无序性的,本身的size过大,作为主键会涉及大量索引重排。
| 名称 | 有序 | 分布式 |
| 自增 | 是 | 否 |
| uuid | 否 | 是 |
因为分布式的优先级大于是否有序,所以数据库不能使用自增主键。
这时候需要一份分布式且有序的主键生成算法:雪花算法。
/**
* @author qushen
* @create 2022/5/29 10:51
*/
public class SnowFlake {
/**
* 组成部分
*/
//最高符号为0
//时间戳
private final long fixedTimeStamp=1234567L;
//机房id
private long computerRoomId;
//机器id
private long machineId;
//序列号 默认初始值为0
private long sequence =0L;
/**
* 设置每个组所占用的bit
*/
//最高符 占用1bit
//时间戳 占用41bit
//机房id 占用5bit
private final long computerRoomBitCnt=5L;
//机器id 占用5bit
private final long machineBitCnt=5L;
//序列号 占用12bit
private final long sequenceBitCnt=12L;
/**
* 设置每个组 位移的位数
*/
//机器id 左移12位(序列号所占的位数)
private final long machineIdShift=sequenceBitCnt;
//机房id 左移12+5位(序列号+机器id所占的位数)
private final long computerRoomIdShift=sequenceBitCnt+machineIdShift;
//时间戳 左移12+5+5位(序列号+机器id+机房id所占的位数)
private final long timeStampShift=computerRoomIdShift+computerRoomBitCnt;
/**
* 聚合信息
*/
//支持的最大 机房id为31位=2^5-1
private final long maxComputerRoomId=-1 ^(-1 << computerRoomBitCnt);
//支持的最大 机器id为31位=2^5-1
private final long maxMachineId=-1 ^(-1 << machineBitCnt);
//序列号掩码
private final long sequenceMask=-1 ^(-1 << sequenceBitCnt);
//上一次生成的时间戳
private long lastTimeStamp=-1L;
public SnowFlake(long computerRoomId,long machineId){
if(computerRoomId<0 || computerRoomId>maxComputerRoomId){
throw new IllegalArgumentException("computerRoomId out of range");
}
if(machineId<0 || machineId>maxMachineId){
throw new IllegalArgumentException("machineId out of range");
}
this.computerRoomId=computerRoomId;
this.machineId=machineId;
}
/**
* 返回毫秒级的时间戳
* @return
*/
protected long getCurrentTime(){
return System.currentTimeMillis();
}
protected synchronized long getNexId(){
//拿到时间戳
long currentTimeStamp =getCurrentTime();
if (currentTimeStamp==lastTimeStamp){
sequence = (sequence+1) & sequenceMask; //取模
//代表该毫秒级所能生成的唯一id已经使用完了
if(sequence == 0){
currentTimeStamp = getNexMillis();
}
}else {
sequence = 0;
}
lastTimeStamp =currentTimeStamp;
//唯一Id
return (currentTimeStamp - fixedTimeStamp<< timeStampShift) |
(computerRoomId << computerRoomIdShift) |
(maxMachineId << machineIdShift) |
sequence ;
}
protected long getNexMillis(){
long currentTimeStamp=getCurrentTime();
while(currentTimeStamp<=lastTimeStamp){
currentTimeStamp =getCurrentTime();
}
return currentTimeStamp;
}
public static void main(String[] args) {
SnowFlake snowFlake = new SnowFlake(0, 0);
System.out.println(snowFlake.getNexId());
}
}
更多推荐


所有评论(0)