中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

收藏的網(wǎng)站從做系統(tǒng)后找不到了東莞關(guān)鍵詞優(yōu)化推廣

收藏的網(wǎng)站從做系統(tǒng)后找不到了,東莞關(guān)鍵詞優(yōu)化推廣,企業(yè)網(wǎng)絡(luò)營銷策略,php工具箱是直接做網(wǎng)站的嗎文章目錄 前言1. 自增ID(Auto-Increment)2. GUID (Globally Unique Identifier)3. 雪花算法(Snowflake)處理時鐘回撥的方法1. 簡單等待2. 配置時鐘回撥安全窗口3. 使用不同的機器 ID 小結(jié)穩(wěn)定的雪花算法實現(xiàn)方案示例實現(xiàn)1. 定義雪…

文章目錄

  • 前言
      • 1. 自增ID(Auto-Increment)
      • 2. GUID (Globally Unique Identifier)
      • 3. 雪花算法(Snowflake)
      • 處理時鐘回撥的方法
        • 1. 簡單等待
        • 2. 配置時鐘回撥安全窗口
        • 3. 使用不同的機器 ID
      • 小結(jié)
      • 穩(wěn)定的雪花算法實現(xiàn)方案
      • 示例實現(xiàn)
        • 1. 定義雪花算法類
        • 2. 使用 Redis 或數(shù)據(jù)庫實現(xiàn)分布式唯一 ID
      • 解釋
      • 小結(jié)
      • 其他方法
      • 總結(jié)


前言

數(shù)據(jù)庫主鍵的設(shè)計是數(shù)據(jù)庫架構(gòu)中的一個重要環(huán)節(jié),不同的主鍵生成策略適用于不同的場景和需求


以下是幾種常見的主鍵設(shè)計方法及其優(yōu)缺點比較:

1. 自增ID(Auto-Increment)

優(yōu)點:

  • 實現(xiàn)簡單,數(shù)據(jù)庫自動管理,無需開發(fā)者介入。
  • 遞增的特性使得數(shù)據(jù)插入速度快,因為插入總是發(fā)生在索引的末尾。
  • 易于理解和使用,便于查詢和排序。

缺點:

  • 分布式系統(tǒng)中難以保證全局唯一,因為每個節(jié)點的計數(shù)器獨立增長。
  • 數(shù)據(jù)泄露風(fēng)險,自增ID容易暴露數(shù)據(jù)庫的規(guī)模和增長速度。
  • 如果發(fā)生大量刪除操作,可能導(dǎo)致主鍵ID不連續(xù),影響美觀但不影響功能。

2. GUID (Globally Unique Identifier)

優(yōu)點:

  • 全球唯一,無論在任何系統(tǒng)、任何地點生成,都能保證唯一性。
  • 無需依賴數(shù)據(jù)庫,可以在客戶端生成,適合分布式系統(tǒng)。
  • 支持提前生成ID,有利于并行處理和離線操作。

缺點:

  • 長度較大(通常為32字符),占用更多的存儲空間和索引空間。
  • 無序的特性可能導(dǎo)致索引碎片,降低插入性能。
  • 不易讀,不便于人工識別和調(diào)試。

3. 雪花算法(Snowflake)

雪花算法(Snowflake Algorithm)是一種用于生成唯一ID的算法,最初由Twitter公司開發(fā)。它是為了解決分布式系統(tǒng)中生成全局唯一ID的需求而設(shè)計的。在分布式系統(tǒng)中,如果不同節(jié)點生成的ID可能會發(fā)生沖突,這就需要一種機制來保證生成的ID在整個系統(tǒng)中唯一。

雪花算法的設(shè)計考慮了以下幾個因素:

  1. 時間戳(Timestamp):使用當(dāng)前時間來確保生成的ID是遞增的,這樣可以保證生成的ID是有序的。
  2. 機器ID(Machine ID):將機器的唯一標(biāo)識(比如機器的MAC地址)作為一部分ID,確保不同機器生成的ID不會沖突。
  3. 序列號(Sequence Number):用來解決同一毫秒內(nèi)生成多個ID時的沖突問題。

Java中如何使用雪花算法來設(shè)計數(shù)據(jù)庫主鍵呢?下面是一個簡單的示例:

public class SnowflakeIdGenerator {// 定義機器ID,可以通過配置文件或其他方式設(shè)置private long machineId;// 定義序列號private long sequence = 0L;// 定義初始時間戳private long twepoch = 1622874000000L; // 2021-06-05 00:00:00// 定義各部分占位數(shù)private long machineIdBits = 5L;private long maxMachineId = -1L ^ (-1L << machineIdBits);private long sequenceBits = 12L;private long sequenceMask = -1L ^ (-1L << sequenceBits);// 定義機器ID左移位數(shù)private long machineIdShift = sequenceBits;// 定義時間戳左移位數(shù)private long timestampLeftShift = sequenceBits + machineIdBits;// 上次生成ID的時間戳private long lastTimestamp = -1L;public SnowflakeIdGenerator(long machineId) {if (machineId > maxMachineId || machineId < 0) {throw new IllegalArgumentException("Machine ID can't be greater than " + maxMachineId + " or less than 0");}this.machineId = machineId;}public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds");}if (lastTimestamp == timestamp) {sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {// 當(dāng)同一毫秒內(nèi)的序列號超過上限時,等待下一毫秒timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;return ((timestamp - twepoch) << timestampLeftShift) | (machineId << machineIdShift) | sequence;}private long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}public static void main(String[] args) {SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1); // 傳入機器IDfor (int i = 0; i < 10; i++) {System.out.println(idGenerator.nextId());}}
}

在這個示例中,我們通過nextId()方法來生成雪花算法生成的唯一ID。首先,我們需要設(shè)置一個機器ID,確保不同的機器有不同的ID。然后,調(diào)用nextId()方法即可生成一個唯一的ID,這個ID包含了時間戳、機器ID和序列號三部分。最后,我們可以將生成的ID作為數(shù)據(jù)庫表的主鍵。

值得注意的是,雪花算法生成的ID是趨勢遞增的,因此在數(shù)據(jù)庫中使用時可能會帶來一定的優(yōu)勢,比如輔助索引的性能優(yōu)化。但也要注意在高并發(fā)情況下可能出現(xiàn)的一些問題,比如時鐘回撥等。

優(yōu)點:

  • 結(jié)合了自增ID和GUID的優(yōu)點,生成的ID是趨勢遞增的,且全局唯一。
  • 高性能,適用于分布式環(huán)境,能夠按需分配workerId和數(shù)據(jù)中心id,保證唯一性。
  • ID較短(一般為64位),相比GUID節(jié)省存儲空間。
  • 有序性有助于索引優(yōu)化。

缺點:

  • 需要一個中心節(jié)點(或者多個,但需要協(xié)調(diào))來生成ID,有一定的運維成本。
  • 時鐘回撥問題可能會影響ID的生成,需要特殊處理。

然而,雪花算法依賴于時間戳,因此時鐘回撥(clock rollback)會對其造成問題。

處理時鐘回撥的方法

1. 簡單等待

當(dāng)檢測到時鐘回撥時,直接等待直到時間回到正確的時間。這是最簡單的處理方式,但會導(dǎo)致 ID 生成暫停一段時間。

public class SnowflakeIdGenerator {private long lastTimestamp = -1L;public synchronized long nextId() {long timestamp = timeGen();// 如果當(dāng)前時間小于上一次生成ID的時間戳,說明系統(tǒng)時鐘回撥if (timestamp < lastTimestamp) {// 等待直到時鐘追上while (timestamp < lastTimestamp) {timestamp = timeGen();}}lastTimestamp = timestamp;return generateId(timestamp);}private long timeGen() {return System.currentTimeMillis();}private long generateId(long timestamp) {// 生成ID的邏輯return timestamp;}
}
2. 配置時鐘回撥安全窗口

允許一定范圍內(nèi)的時鐘回撥,在這個范圍內(nèi)繼續(xù)生成 ID,但如果超出這個范圍則拋出異?;虿扇∑渌胧?/p>

public class SnowflakeIdGenerator {private long lastTimestamp = -1L;private static final long MAX_BACKWARD_MS = 5L; // 允許的最大時鐘回撥時間public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {long offset = lastTimestamp - timestamp;if (offset <= MAX_BACKWARD_MS) {// 等待,直到時鐘追上try {Thread.sleep(offset + 1);} catch (InterruptedException e) {throw new RuntimeException(e);}timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards. Refusing to generate id");}} else {throw new RuntimeException("Clock moved backwards. Refusing to generate id");}}lastTimestamp = timestamp;return generateId(timestamp);}private long timeGen() {return System.currentTimeMillis();}private long generateId(long timestamp) {// 生成ID的邏輯return timestamp;}
}
3. 使用不同的機器 ID

在分布式系統(tǒng)中,每臺機器有唯一的機器 ID。當(dāng)檢測到時鐘回撥時,改變機器 ID 來避免沖突。這種方法需要協(xié)調(diào)機器 ID 的分配。

public class SnowflakeIdGenerator {private long lastTimestamp = -1L;private long machineId;private static final long MAX_MACHINE_ID = 1023L;public SnowflakeIdGenerator(long machineId) {if (machineId < 0 || machineId > MAX_MACHINE_ID) {throw new IllegalArgumentException("Machine ID out of range");}this.machineId = machineId;}public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {machineId = (machineId + 1) & MAX_MACHINE_ID;if (machineId == 0) {// 如果機器ID回到0,說明時鐘回撥過大,拒絕生成IDthrow new RuntimeException("Clock moved backwards. Refusing to generate id");}timestamp = timeGen();}lastTimestamp = timestamp;return generateId(timestamp, machineId);}private long timeGen() {return System.currentTimeMillis();}private long generateId(long timestamp, long machineId) {// 生成ID的邏輯,包含時間戳和機器IDreturn (timestamp << 22) | (machineId << 12);}
}

小結(jié)

  1. 簡單等待:當(dāng)檢測到時鐘回撥時,等待直到時鐘恢復(fù)到正確時間。這種方法簡單但會導(dǎo)致 ID 生成暫停。
  2. 時鐘回撥安全窗口:允許一定范圍內(nèi)的時鐘回撥,如果超出這個范圍則拋出異常或采取其他措施。
  3. 不同的機器 ID:當(dāng)檢測到時鐘回撥時,改變機器 ID 來避免沖突。這種方法需要協(xié)調(diào)機器 ID 的分配。

穩(wěn)定的雪花算法實現(xiàn)方案

以下是一個經(jīng)過優(yōu)化的方案,涵蓋時鐘回撥問題、分布式系統(tǒng)中的唯一性問題和高可用性問題

  1. 機器 ID 和數(shù)據(jù)中心 ID:通過配置不同的機器 ID 和數(shù)據(jù)中心 ID 來確保分布式系統(tǒng)中的唯一性。
  2. 時鐘回撥處理:使用遞增序列和緩存的時間戳來處理時鐘回撥問題。
  3. 高可用性:結(jié)合 Redis 或數(shù)據(jù)庫來生成分布式唯一 ID。

示例實現(xiàn)

1. 定義雪花算法類
public class SnowflakeIdGenerator {private static final long EPOCH = 1609459200000L; // 自定義紀(jì)元時間(2021-01-01)private static final long DATA_CENTER_ID_BITS = 5L;private static final long MACHINE_ID_BITS = 5L;private static final long SEQUENCE_BITS = 12L;private static final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);private static final long MAX_MACHINE_ID = ~(-1L << MACHINE_ID_BITS);private static final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);private static final long MACHINE_ID_SHIFT = SEQUENCE_BITS;private static final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS;private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + MACHINE_ID_BITS + DATA_CENTER_ID_BITS;private final long dataCenterId;private final long machineId;private long sequence = 0L;private long lastTimestamp = -1L;public SnowflakeIdGenerator(long dataCenterId, long machineId) {if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {throw new IllegalArgumentException(String.format("DataCenter ID can't be greater than %d or less than 0", MAX_DATA_CENTER_ID));}if (machineId > MAX_MACHINE_ID || machineId < 0) {throw new IllegalArgumentException(String.format("Machine ID can't be greater than %d or less than 0", MAX_MACHINE_ID));}this.dataCenterId = dataCenterId;this.machineId = machineId;}public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards. Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds");}if (timestamp == lastTimestamp) {sequence = (sequence + 1) & MAX_SEQUENCE;if (sequence == 0) {timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;return ((timestamp - EPOCH) << TIMESTAMP_SHIFT)| (dataCenterId << DATA_CENTER_ID_SHIFT)| (machineId << MACHINE_ID_SHIFT)| sequence;}private long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}
}
2. 使用 Redis 或數(shù)據(jù)庫實現(xiàn)分布式唯一 ID

為了進一步提高高可用性和唯一性,可以結(jié)合 Redis 或數(shù)據(jù)庫實現(xiàn)分布式唯一 ID 生成。這里是一個使用 Redis 的示例:

import redis.clients.jedis.Jedis;public class DistributedIdGenerator {private final SnowflakeIdGenerator snowflakeIdGenerator;private final Jedis jedis;public DistributedIdGenerator(long dataCenterId, long machineId, String redisHost, int redisPort) {this.snowflakeIdGenerator = new SnowflakeIdGenerator(dataCenterId, machineId);this.jedis = new Jedis(redisHost, redisPort);}public long nextId() {long id = snowflakeIdGenerator.nextId();String key = "snowflake:" + id;while (jedis.exists(key)) {id = snowflakeIdGenerator.nextId();key = "snowflake:" + id;}jedis.setex(key, 3600, "1"); // 設(shè)置過期時間,避免長期存儲return id;}
}

解釋

  1. 基本雪花算法

    • EPOCH:自定義的紀(jì)元時間。
    • DATA_CENTER_ID_BITS、MACHINE_ID_BITSSEQUENCE_BITS:數(shù)據(jù)中心 ID、機器 ID 和序列號的位數(shù)。
    • nextId 方法:生成唯一 ID,并處理時鐘回撥問題。
  2. 分布式唯一 ID

    • 使用 Redis 確保 ID 唯一性:在生成 ID 后,將其存儲在 Redis 中,檢查是否重復(fù)。
    • jedis.setex(key, 3600, "1"):使用帶過期時間的鍵來避免長期存儲。
  3. 時鐘回撥處理

    • 當(dāng)檢測到時鐘回撥時,拋出異常或等待時間前進。
    • 使用 tilNextMillis 方法等待直到時間前進。

小結(jié)

這種方案結(jié)合了雪花算法的高性能和 Redis 的分布式存儲能力,解決了時鐘回撥問題,并確保在分布式環(huán)境下生成唯一 ID。通過這些措施,可以實現(xiàn)一個穩(wěn)定、高效的分布式唯一 ID 生成系統(tǒng)。

其他方法

  • 復(fù)合主鍵:結(jié)合多個字段作為主鍵,適用于表中沒有自然唯一標(biāo)識符的場景。但增加了查詢和維護的復(fù)雜性。
  • 業(yè)務(wù)相關(guān)ID:如訂單號,易于理解且與業(yè)務(wù)緊密相關(guān),但可能需要額外的邏輯來保證唯一性,且擴展性較差。

總結(jié)

選擇哪種主鍵生成策略取決于具體的應(yīng)用場景:

  • 對于單體應(yīng)用或簡單的分布式系統(tǒng),自增ID可能是最簡單高效的選擇。
  • 在分布式系統(tǒng)中,尤其是跨多個數(shù)據(jù)中心時,雪花算法因其高性能和全局唯一性成為優(yōu)選。
  • 當(dāng)全局唯一性是首要考慮因素,且對存儲空間不太敏感時,GUID是合適的選擇。
  • 具體場景下,也可以根據(jù)業(yè)務(wù)需求考慮復(fù)合主鍵或業(yè)務(wù)相關(guān)ID的方案。
http://www.risenshineclean.com/news/35380.html

相關(guān)文章:

  • 營銷型網(wǎng)站有哪些出名的沈陽seo關(guān)鍵詞排名
  • 政府網(wǎng)站建設(shè)網(wǎng)頁設(shè)計規(guī)范網(wǎng)站seo診斷
  • 做網(wǎng)站客戶沒有付定金seo百度發(fā)包工具
  • 旅行網(wǎng)站開發(fā)需求說明書百度網(wǎng)頁怎么制作
  • 重慶網(wǎng)站制作開發(fā)重慶seo技術(shù)博客
  • 上海博大園林建設(shè)發(fā)展有限公司網(wǎng)站app推廣代理平臺
  • 網(wǎng)站備案需要多少錢免費宣傳平臺有哪些
  • 建設(shè)網(wǎng)站的叫什么職位谷歌搜索引擎入口google
  • 做商城網(wǎng)站需要什么排行榜軟件
  • 安卓端開發(fā)優(yōu)化排名推廣教程網(wǎng)站
  • pc官方網(wǎng)站seo推廣優(yōu)化外包價格
  • 省示范院校建設(shè)網(wǎng)站seo入門教程網(wǎng)盤
  • 網(wǎng)站設(shè)計師培訓(xùn)學(xué)校吳中seo頁面優(yōu)化推廣
  • 網(wǎng)站橫幅代碼優(yōu)化seo招聘
  • 購物網(wǎng)站APP廣州seo公司品牌
  • 找網(wǎng)站公司做網(wǎng)站的陷阱友情鏈接代碼
  • 工廠采購信息網(wǎng)深圳優(yōu)化公司哪家好
  • 林州網(wǎng)站建設(shè)服務(wù)關(guān)鍵詞分類哪八種
  • 網(wǎng)站建設(shè) 石景山windows優(yōu)化大師卸載不了
  • 模板網(wǎng)站制作成都百度推廣優(yōu)化創(chuàng)意
  • 西昌有做網(wǎng)站的公司嗎怎樣推廣公司的網(wǎng)站
  • 日本一級做a在線播放免費視頻網(wǎng)站網(wǎng)站制作詳細流程
  • 美橙網(wǎng)站建設(shè)怎么做全國疫情最新數(shù)據(jù)
  • 學(xué)校網(wǎng)站開發(fā)招標(biāo)網(wǎng)絡(luò)推廣優(yōu)化品牌公司
  • 美女做曖曖網(wǎng)站關(guān)鍵詞排名推廣軟件
  • 虎門仿做網(wǎng)站一鍵生成個人網(wǎng)站
  • 怎么把做的網(wǎng)站放到騰訊云里面代寫文章哪里找寫手
  • 聊城做網(wǎng)站優(yōu)化百度投訴中心人工電話
  • 做宣傳可以在哪些網(wǎng)站上發(fā)布如何營銷推廣自己的產(chǎn)品
  • 臨沂手機網(wǎng)站建設(shè)google學(xué)術(shù)搜索