起因
TEAM GARDEN 本來ID是自增的,后面發(fā)現(xiàn)自增ID比較麻煩,有問題:
不可控的間隔: 如果你在插入數(shù)據(jù)時(shí),中途刪除了一些行,導(dǎo)致自增的ID出現(xiàn)間隔,那么新插入的行會(huì)填充這些間隔,可能會(huì)導(dǎo)致ID序列不連續(xù),不利于數(shù)據(jù)分析和理解。
不適用于批量插入: 在批量插入數(shù)據(jù)時(shí),自增主鍵可能會(huì)導(dǎo)致性能問題。因?yàn)槊看尾迦攵夹枰i定表,以獲取下一個(gè)自增ID。這可能導(dǎo)致大量的表鎖等待,從而影響性能。
主鍵沖突: 在某些情況下,例如數(shù)據(jù)導(dǎo)入或數(shù)據(jù)同步,可能會(huì)出現(xiàn)主鍵沖突的情況。如果數(shù)據(jù)源中的主鍵與目標(biāo)數(shù)據(jù)庫中的自增ID沖突,就會(huì)導(dǎo)致插入失敗。
難以預(yù)測的ID值: 自增ID的值通常是由數(shù)據(jù)庫管理的,這意味著你不能預(yù)測下一個(gè)ID是什么。在某些情況下,你可能需要對(duì)生成的ID值進(jìn)行控制或預(yù)測。
不支持外部數(shù)據(jù)源: 如果需要將外部數(shù)據(jù)源(例如其他數(shù)據(jù)庫或數(shù)據(jù)文件)與數(shù)據(jù)庫中的表關(guān)聯(lián),自增主鍵可能不太適合。你無法為外部數(shù)據(jù)源生成有效的自增ID。
所以決定自己寫一個(gè)ID生成的工具
代碼
public class SnowflakeIdGenerator {
private static final long START_TIMESTAMP = 1630435200000L; // 2021-09-01 00:00:00
private static final long MACHINE_ID_BITS = 5L;
private static final long SEQUENCE_BITS = 12L;
private static final long MAX_MACHINE_ID = ~(-1L << MACHINE_ID_BITS);
private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);
private long machineId;
private long sequence = 0L;
private long lastTimestamp = -1L;
public SnowflakeIdGenerator(long machineId) {
if (machineId < 0 || machineId > MAX_MACHINE_ID) {
throw new IllegalArgumentException("Machine ID must be between 0 and " + MAX_MACHINE_ID);
}
this.machineId = machineId;
}
public synchronized long generateId() {
long currentTimestamp = System.currentTimeMillis();
if (currentTimestamp < lastTimestamp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate ID.");
}
if (currentTimestamp == lastTimestamp) {
sequence = (sequence + 1) & MAX_SEQUENCE;
if (sequence == 0) {
currentTimestamp = nextTimestamp(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = currentTimestamp;
long id = ((currentTimestamp - START_TIMESTAMP) << (MACHINE_ID_BITS + SEQUENCE_BITS))
| (machineId << SEQUENCE_BITS)
| sequence;
return id;
}
private long nextTimestamp(long lastTimestamp) {
long currentTimestamp = System.currentTimeMillis();
while (currentTimestamp <= lastTimestamp) {
currentTimestamp = System.currentTimeMillis();
}
return currentTimestamp;
}
}
使用文章來源:http://www.zghlxwxcb.cn/news/detail-670873.html
resumeEntity.setId(new SnowflakeIdGenerator(1).generateId());
結(jié)論
這樣生成的ID是有序的、適合大數(shù)據(jù)量的、簡單、可預(yù)測且不依賴外部資源的。文章來源地址http://www.zghlxwxcb.cn/news/detail-670873.html
到了這里,關(guān)于無分布式鎖的ID生成的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!