最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

BloomFilter如何快速檢查用戶名重復(fù)

 更新時(shí)間:2025年04月19日 09:34:20   作者:埃澤漫筆  
這篇文章主要介紹了BloomFilter如何快速檢查用戶名重復(fù)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

背景

在我們的項(xiàng)目中,用戶名是不能重復(fù)的,因?yàn)樵跀?shù)藏項(xiàng)目中,用戶名的唯一性很重要,因?yàn)椴仄芬鏊菰?,要確保整個(gè)鏈路上的參與者的唯一性,雖然用戶 id 也是我唯一的,但是頁(yè)面上展示的時(shí)候不能用 id 呀。

有些網(wǎng)站,比如淘寶網(wǎng),也是要求用戶名唯一的。

所以為了實(shí)現(xiàn)這個(gè)用戶在注冊(cè),改名的時(shí)候的用戶名的唯一性,我們一般是先從數(shù)據(jù)庫(kù)查詢是否存在,不存在則讓用戶注冊(cè)。

但是為了考慮到性能,我們會(huì)把用戶名存儲(chǔ)到緩存中,一般使用 redis 緩存。

那既然都用了緩存了,那還不如干脆直接就用布隆過(guò)濾器來(lái)存儲(chǔ),既可以做重復(fù)校驗(yàn),又能節(jié)省空間。所以,我們?cè)谟脩裘貜?fù)檢驗(yàn)這里就用到了布隆過(guò)濾器。

簡(jiǎn)介

布隆過(guò)濾器是一種數(shù)據(jù)結(jié)構(gòu),用于快速檢索一個(gè)元素是否可能存在于一個(gè)集合(bit 數(shù)組)中。

它的基本原理是利用多個(gè)哈希函數(shù),將一個(gè)元素映射成多個(gè)位,然后將這些位設(shè)置為 1。當(dāng)查詢一個(gè)元素時(shí),如果這些位都被設(shè)置為 1,則認(rèn)為元素可能存在于集合中,否則肯定不存在。

所以,布隆過(guò)濾器可以準(zhǔn)確的判斷一個(gè)元素是否一定不存在,但是因?yàn)楣_突的存在,所以他沒(méi)辦法判斷一個(gè)元素一定存在。只能判斷可能存在。

代碼實(shí)現(xiàn)

所以,我們定義了兩個(gè)方法,nickNameExist用于判斷是否存在,addNickName用于向布隆過(guò)濾器中添加已注冊(cè)的用戶名。

public boolean nickNameExist(String nickName) {
    //如果布隆過(guò)濾器中存在,再進(jìn)行數(shù)據(jù)庫(kù)二次判斷
    if (this.bloomFilter.contains(nickName)) {
        return userMapper.findByNickname(nickName) != null;
    }

    return false;
}

private boolean addNickName(String nickName) {
    return this.bloomFilter.add(nickName);
}

這里nickNameExist方法,先從布隆過(guò)濾器中查詢,如果如果查到了,再去數(shù)據(jù)庫(kù)中查了一下,為啥呢?

因?yàn)椴悸∵^(guò)濾器有誤判的,存在一定的誤判率,他會(huì)把不存在的用戶判斷為存在,所以當(dāng)檢查結(jié)果是存在的時(shí)候,需要再次判斷一次。

因?yàn)橛脩糇?cè)的時(shí)候,大多數(shù)情況下都是不重復(fù)的,所以我們可以快速的用布隆過(guò)濾器進(jìn)行不存在的判斷。

這里的bloomFilter是這樣被初始化出來(lái)的:

private RBloomFilter<String> bloomFilter;

@Override
public void afterPropertiesSet() throws Exception {
    this.bloomFilter = redissonClient.getBloomFilter("nickName");
    if (!bloomFilter.isExists()) {
        this.bloomFilter.tryInit(10000000L, 0.01);
    }
}

我們?cè)O(shè)置了10000000的容量,誤判率是0.01。

然后在修改用戶名這里,用這樣的方式進(jìn)行調(diào)用的。

如果用戶名修改了怎么辦?

如果原來(lái)用戶名是Aizer,被放到布隆過(guò)濾器了,但是后面我改成 Aizer666了,那么意味著 Aizer已經(jīng)沒(méi)有了,那么如何從布隆過(guò)濾器刪除呢?

很遺憾,不支持!

那怎么辦呢?

其實(shí)問(wèn)題也不大,因?yàn)椴悸∵^(guò)濾器本身就存在誤判率,但我們檢查布隆過(guò)濾器發(fā)現(xiàn)存在的時(shí)候,還是會(huì)去數(shù)據(jù)庫(kù)再確認(rèn)一遍的。

只要我們定期的重建一下布隆過(guò)濾器就行了。重建就是都刪了,然后重新構(gòu)建。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入學(xué)習(xí)Java單元測(cè)試(Junit+Mock+代碼覆蓋率)

    深入學(xué)習(xí)Java單元測(cè)試(Junit+Mock+代碼覆蓋率)

    在做單元測(cè)試時(shí),代碼覆蓋率常常被拿來(lái)作為衡量測(cè)試好壞的指標(biāo),甚至,用代碼覆蓋率來(lái)考核測(cè)試任務(wù)完成情況,比如,代碼覆蓋率必須達(dá)到80%或 90%。下面我們就來(lái)詳細(xì)學(xué)習(xí)下java單元測(cè)試吧
    2019-06-06
  • Java8中的default關(guān)鍵字詳解

    Java8中的default關(guān)鍵字詳解

    這篇文章主要介紹了Java8中的default關(guān)鍵字詳解,在實(shí)現(xiàn)某個(gè)接口的時(shí)候,需要實(shí)現(xiàn)該接口所有的方法,這個(gè)時(shí)候default關(guān)鍵字就派上用場(chǎng)了。通過(guò)default關(guān)鍵字定義的方法,集成該接口的方法不需要去實(shí)現(xiàn)該方法,需要的朋友可以參考下
    2023-08-08
  • java String的intern方法

    java String的intern方法

    本文主要介紹java 中String 的intern方法,這里主要通過(guò)實(shí)例來(lái)說(shuō)明不同版本的JDK,intern方法的對(duì)比,有需要的小伙伴可以參考下
    2016-07-07
  • IntelliJ Idea2017如何修改緩存文件的路徑

    IntelliJ Idea2017如何修改緩存文件的路徑

    這篇文章主要介紹了IntelliJ Idea2017如何修改緩存文件的路徑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java?如何獲取某年的第一天和最后一天

    Java?如何獲取某年的第一天和最后一天

    在統(tǒng)計(jì)的數(shù)據(jù)是時(shí)候,要統(tǒng)計(jì)某年的數(shù)據(jù),開(kāi)始時(shí)間是某年的第一天,結(jié)束時(shí)間是某年的最后一天,該如何獲取某年的第一天和最后一天,今天通過(guò)本文介紹下Java獲取某年的第一天和最后一天,需要的朋友可以參考下
    2023-07-07
  • Springboot通過(guò)配置WebMvcConfig處理Cors非同源訪問(wèn)跨域問(wèn)題

    Springboot通過(guò)配置WebMvcConfig處理Cors非同源訪問(wèn)跨域問(wèn)題

    這篇文章主要介紹了Springboot通過(guò)配置WebMvcConfig處理Cors非同源訪問(wèn)跨域問(wèn)題,關(guān)于Cors跨域的問(wèn)題,前端有代理和jsonp的常用方式解決這種非同源的訪問(wèn)拒絕策略
    2023-04-04
  • Java?延時(shí)隊(duì)列及簡(jiǎn)單使用方式詳解

    Java?延時(shí)隊(duì)列及簡(jiǎn)單使用方式詳解

    這篇文章主要介紹了Java延時(shí)隊(duì)列簡(jiǎn)單使用方式,通過(guò)本文學(xué)習(xí)知道延時(shí)隊(duì)列是什么可以用來(lái)干什么,本文通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • Springboot集成Mybatis-Flex的示例詳解

    Springboot集成Mybatis-Flex的示例詳解

    Mybatis-Flex 是一個(gè)優(yōu)雅的?Mybatis 增強(qiáng)框架,它非常輕量、同時(shí)擁有極高的性能與靈活性,本文主要介紹了Springboot集成Mybatis-Flex的示例詳解,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例

    Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例

    這篇文章主要介紹了Java將byte[]轉(zhuǎn)圖片存儲(chǔ)到本地的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • 詳解如何熱更新線上的Java服務(wù)器代碼

    詳解如何熱更新線上的Java服務(wù)器代碼

    這篇文章主要介紹了詳解如何熱更新線上的Java服務(wù)器代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04

最新評(píng)論

章丘市| 周口市| 叶城县| 昌宁县| 西贡区| 历史| 长顺县| 广宁县| 南部县| 建宁县| 长兴县| 呼伦贝尔市| 庆阳市| 宜宾县| 大田县| 石渠县| 霸州市| 百色市| 东台市| 桑植县| 收藏| 抚远县| 邹平县| 车险| 珲春市| 肇庆市| 河南省| 正镶白旗| 黑河市| 石楼县| 开远市| 北海市| 齐齐哈尔市| 铜山县| 巴林左旗| 揭阳市| 丹棱县| 许昌市| 红桥区| 诸城市| 固原市|