主键ID生成方式
数据库自增(mysql)
自增ID是数据库系统提供的功能,通常每插入一条记录,该字段自动加1。
CREATE TABLE Users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100)
);
mybatis主键自增(mysql)
useGeneratedKeys设置自动生成主键,keyProperty设置主键列名,该方式适用于大多数关系型数据库
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO Users (username) VALUES (#{username})
</insert>
UUID
UUID是一种128位的全局唯一标识,通常表示为32个十六进制数字。UUID的生成通常依赖于标准库或工具。
import java.util.UUID;
String userId = UUID.randomUUID().toString();
雪花算法
雪花算法生成的ID是一个64位的整型,包含时间戳、机器ID和序列号。通常格式为:
0 ms 1970-01-01 00:00:00 +0000 0000-12-31 23:59:59.999 00 000000
public class SnowflakeIdGenerator {
private final long workerId; // 机器ID
private final long datacenterId; // 数据中心ID
private static final long SEQUENCE_BITS = 12L; // 支持的序列数
private static final long WORKER_ID_BITS = 5L; // 机器ID的位数
private static final long DATACENTER_ID_BITS = 5L; // 数据中心ID的位数
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS); // max workerId
private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS); // max datacenterId
private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); // max sequence
private long sequence = 0; // 当前序列
private long lastTimestamp = -1;
public SnowflakeIdGenerator(long workerId, long datacenterId) {
if (workerId > MAX_WORKER_ID || workerId < 0 ||
datacenterId > MAX_DATACENTER_ID || datacenterId < 0) {
throw new IllegalArgumentException("workerId or datacenterId is invalid");
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
public synchronized long nextId() {
long timestamp = System.currentTimeMillis();
if (timestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & SEQUENCE_MASK;
if (sequence == 0) {
timestamp = waitNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}
lastTimestamp = timestamp;
return ((timestamp << (WORKER_ID_BITS + DATACENTER_ID_BITS + SEQUENCE_BITS)) |
(datacenterId << (WORKER_ID_BITS + SEQUENCE_BITS)) |
(workerId << SEQUENCE_BITS) | sequence);
}
private long waitNextMillis(long lastTimestamp) {
long timestamp = System.currentTimeMillis();
while (timestamp <= lastTimestamp) {
timestamp = System.currentTimeMillis();
}
return timestamp;
}
}
// 使用示例
SnowflakeIdGenerator generator = new SnowflakeIdGenerator(1, 1);
long id = generator.nextId();
IdUtil
- UUID
- 生成uuid带-
IdUtil.randomUUID()
- 生成uuid不带-
IdUtil.simpleUUID()
- 生成uuid带-,性能更好
IdUtil.fastUUID()
- 生成uuid不带-,性能更好
IdUtil.fastSimpleUUID()
- ObjectId(mongodb)
生成mongodb主键
IdUtil.objectId()
- Snowflake
Snowflake snowflake = IdUtil.getSnowflake(); long l = snowflake.nextId();