国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

如何在十億級(jí)別用戶中檢查用戶名是否存在?

這篇具有很好參考價(jià)值的文章主要介紹了如何在十億級(jí)別用戶中檢查用戶名是否存在?。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

不知道大家有沒(méi)有留意過(guò),在使用一些app注冊(cè)的時(shí)候,提示你用戶名已經(jīng)被占用了,需要更換一個(gè),這是如何實(shí)現(xiàn)的呢?你可能想這不是很簡(jiǎn)單嗎,去數(shù)據(jù)庫(kù)里查一下有沒(méi)有不就行了嗎,那么假如用戶數(shù)量很多,達(dá)到數(shù)億級(jí)別呢,這又該如何是好?

數(shù)據(jù)庫(kù)方案
第一種方案就是查數(shù)據(jù)庫(kù)的方案,大家都能夠想到,代碼如下:

public class UsernameUniquenessChecker {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database";
    private static final String DB_USER = "your_username";
    private static final String DB_PASSWORD = "your_password";

    public static boolean isUsernameUnique(String username) {
        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            String sql = "SELECT COUNT(*) FROM users WHERE username = ?";
            try (PreparedStatement stmt = conn.prepareStatement(sql)) {
                stmt.setString(1, username);
                try (ResultSet rs = stmt.executeQuery()) {
                    if (rs.next()) {
                        int count = rs.getInt(1);
                        return count == 0; // If count is 0, username is unique
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false; // In case of an error, consider the username as non-unique
    }

    public static void main(String[] args) {
        String desiredUsername = "new_user";
        boolean isUnique = isUsernameUnique(desiredUsername);
        if (isUnique) {
            System.out.println("Username '" + desiredUsername + "' is unique. Proceed with registration.");
        } else {
            System.out.println("Username '" + desiredUsername + "' is already in use. Choose a different one.");
        }
    }
}

這種方法會(huì)帶來(lái)如下問(wèn)題:

性能問(wèn)題,延遲高 。 如果數(shù)據(jù)量很大,查詢速度慢。另外,數(shù)據(jù)庫(kù)查詢涉及應(yīng)用程序服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器之間的網(wǎng)絡(luò)通信。建立連接、發(fā)送查詢和接收響應(yīng)所需的時(shí)間也會(huì)導(dǎo)致延遲。
數(shù)據(jù)庫(kù)負(fù)載過(guò)高。頻繁執(zhí)行 SELECT 查詢來(lái)檢查用戶名唯一性,每個(gè)查詢需要數(shù)據(jù)庫(kù)資源,包括CPU和I/O。
可擴(kuò)展性差。數(shù)據(jù)庫(kù)對(duì)并發(fā)連接和資源有限制。如果注冊(cè)率繼續(xù)增長(zhǎng),數(shù)據(jù)庫(kù)服務(wù)器可能難以處理數(shù)量增加的傳入請(qǐng)求。垂直擴(kuò)展數(shù)據(jù)庫(kù)(向單個(gè)服務(wù)器添加更多資源)可能成本高昂并且可能有限制。

緩存方案

為了解決數(shù)據(jù)庫(kù)調(diào)用用戶名唯一性檢查的性能問(wèn)題,引入了高效的Redis緩存。

public class UsernameCache {

    private static final String REDIS_HOST = "localhost";
    private static final int REDIS_PORT = 6379; 
    private static final int CACHE_EXPIRATION_SECONDS = 3600; 

    private static JedisPool jedisPool;

    // Initialize the Redis connection pool
    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        jedisPool = new JedisPool(poolConfig, REDIS_HOST, REDIS_PORT);
    }

    // Method to check if a username is unique using the Redis cache
    public static boolean isUsernameUnique(String username) {
        try (Jedis jedis = jedisPool.getResource()) {
            // Check if the username exists in the Redis cache
            if (jedis.sismember("usernames", username)) {
                return false; // Username is not unique
            }
        } catch (Exception e) {
            e.printStackTrace();
            // Handle exceptions or fallback to database query if Redis is unavailable
        }
        return true; // Username is unique (not found in cache)
    }

    // Method to add a username to the Redis cache
    public static void addToCache(String username) {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.sadd("usernames", username); // Add the username to the cache set
            jedis.expire("usernames", CACHE_EXPIRATION_SECONDS); // Set expiration time for the cache
        } catch (Exception e) {
            e.printStackTrace();
            // Handle exceptions if Redis cache update fails
        }
    }

    // Cleanup and close the Redis connection pool
    public static void close() {
        jedisPool.close();
    }
}

這個(gè)方案最大的問(wèn)題就是內(nèi)存占用過(guò)大,假如每個(gè)用戶名需要大約 20 字節(jié)的內(nèi)存。你想要存儲(chǔ)10億個(gè)用戶名的話,就需要20G的內(nèi)存。

總內(nèi)存 = 每條記錄的內(nèi)存使用量 * 記錄數(shù) = 20 字節(jié)/記錄 * 1,000,000,000 條記錄 = 20,000,000,000 字節(jié) = 20,000,000 KB = 20,000 MB = 20 GB

布隆過(guò)濾器方案

直接緩存判斷內(nèi)存占用過(guò)大,有沒(méi)有什么更好的辦法呢?布隆過(guò)濾器就是很好的一個(gè)選擇。

那究竟什么布隆過(guò)濾器呢?
布隆過(guò)濾器的原理(二進(jìn)制 + 哈希函數(shù))
假設(shè)布隆過(guò)濾器由 20位二進(jìn)制、 3個(gè)哈希函數(shù)組成,每個(gè)元素經(jīng)過(guò)哈希函數(shù)處理都能生成一個(gè)索引位置。

布隆過(guò)濾器的基礎(chǔ)操作有兩個(gè):添加、查詢

添加元素: 將每一個(gè)哈希函數(shù)生成的索引位置都設(shè)為 1

查詢?cè)厥欠翊嬖冢?/strong>
如果有一個(gè)哈希函數(shù)生成的索引位置不為 1,就代表不存在(100%準(zhǔn)確)
如果每一個(gè)哈希函數(shù)生成的索引位置都為 1,就代表存在(存在一定的誤判率)

如何在十億級(jí)別用戶中檢查用戶名是否存在?,java,數(shù)據(jù)庫(kù)
添加、查詢的時(shí)間復(fù)雜度都是:O(k) ,k 是哈希函數(shù)的個(gè)數(shù)
空間復(fù)雜度是:O(m) ,m 是二進(jìn)制位的個(gè)數(shù)
布隆過(guò)濾器的誤判率(公式)
誤判率 p 受 3 個(gè)因素影響:二進(jìn)制位的個(gè)數(shù) m、哈希函數(shù)的個(gè)數(shù) k、數(shù)據(jù)規(guī)模 n。

誤判率 p 的公式:
如何在十億級(jí)別用戶中檢查用戶名是否存在?,java,數(shù)據(jù)庫(kù)
已知誤判率 p、數(shù)據(jù)規(guī)模 n,求二進(jìn)制位的個(gè)數(shù) m、哈希函數(shù)的個(gè)數(shù) k:

二進(jìn)制位的個(gè)數(shù) m:
如何在十億級(jí)別用戶中檢查用戶名是否存在?,java,數(shù)據(jù)庫(kù)
哈希函數(shù)的個(gè)數(shù) k:
如何在十億級(jí)別用戶中檢查用戶名是否存在?,java,數(shù)據(jù)庫(kù)

總結(jié):

布隆過(guò)濾器(Bloom Filter)是一種數(shù)據(jù)結(jié)構(gòu),用于快速檢查一個(gè)元素是否存在于一個(gè)大型數(shù)據(jù)集中,通常用于在某些情況下快速過(guò)濾掉不可能存在的元素,以減少后續(xù)更昂貴的查詢操作。布隆過(guò)濾器的主要優(yōu)點(diǎn)是它可以提供快速的查找和插入操作,并且在內(nèi)存占用方面非常高效。

布隆過(guò)濾器的核心思想是使用一個(gè)位數(shù)組(bit array)和一組哈希函數(shù)。

位數(shù)組(Bit Array) :布隆過(guò)濾器使用一個(gè)包含大量位的數(shù)組,通常初始化為全0。每個(gè)位可以存儲(chǔ)兩個(gè)值,通常是0或1。這些位被用來(lái)表示元素的存在或可能的存在。
哈希函數(shù)(Hash Functions) :布隆過(guò)濾器使用多個(gè)哈希函數(shù),每個(gè)哈希函數(shù)可以將輸入元素映射到位數(shù)組的一個(gè)或多個(gè)位置。這些哈希函數(shù)必須是獨(dú)立且具有均勻分布特性。
那么具體是怎么做的呢?

添加元素:如上圖所示,當(dāng)將字符串“xuyang”,“alvin”插入布隆過(guò)濾器時(shí),通過(guò)多個(gè)哈希函數(shù)將元素映射到位數(shù)組的多個(gè)位置,然后將這些位置的位設(shè)置為1。
查詢?cè)兀寒?dāng)要檢查一個(gè)元素是否存在于布隆過(guò)濾器中時(shí),通過(guò)相同的哈希函數(shù)將元素映射到位數(shù)組的相應(yīng)位置,然后檢查這些位置的位是否都為1。如果有任何一個(gè)位為0,那么可以確定元素不存在于數(shù)據(jù)集中。但如果所有位都是1,元素可能存在于數(shù)據(jù)集中,但也可能是誤判。
本身redis支持布隆過(guò)濾器的數(shù)據(jù)結(jié)構(gòu),我們用代碼簡(jiǎn)單實(shí)現(xiàn)了解一下:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class BloomFilterExample {
    public static void main(String[] args) {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379);

        try (Jedis jedis = jedisPool.getResource()) {
            // 創(chuàng)建一個(gè)名為 "usernameFilter" 的布隆過(guò)濾器,需要指定預(yù)計(jì)的元素?cái)?shù)量和期望的誤差率
            jedis.bfCreate("usernameFilter", 10000000, 0.01);
            
            // 將用戶名添加到布隆過(guò)濾器
            jedis.bfAdd("usernameFilter", "alvin");
            
            // 檢查用戶名是否已經(jīng)存在
            boolean exists = jedis.bfExists("usernameFilter", "alvin");
            System.out.println("Username exists: " + exists);
        }
    }
}

在上述示例中,我們首先創(chuàng)建一個(gè)名為 “usernameFilter” 的布隆過(guò)濾器,然后使用 bfAdd 將用戶名添加到布隆過(guò)濾器中。最后,使用 bfExists 檢查用戶名是否已經(jīng)存在。

優(yōu)點(diǎn):

節(jié)約內(nèi)存空間,相比使用哈希表等數(shù)據(jù)結(jié)構(gòu),布隆過(guò)濾器通常需要更少的內(nèi)存空間,因?yàn)樗淮鎯?chǔ)實(shí)際元素,而只存儲(chǔ)元素的哈希值。如果以 0.001 誤差概率存儲(chǔ) 10 億條記錄,只需要 1.67 GB 內(nèi)存,對(duì)比原來(lái)的20G,大大的減少了。
高效的查找, 布隆過(guò)濾器可以在常數(shù)時(shí)間內(nèi)(O(1))快速查找一個(gè)元素是否存在于集合中,無(wú)需遍歷整個(gè)集合。
缺點(diǎn):

誤判率存在:布隆過(guò)濾器在判斷元素是否存在時(shí),有一定的誤判率。這意味著在某些情況下,它可能會(huì)錯(cuò)誤地報(bào)告元素存在,但不會(huì)錯(cuò)誤地報(bào)告元素不存在。
不能刪除元素:布隆過(guò)濾器通常不支持從集合中刪除元素,因?yàn)閯h除一個(gè)元素會(huì)影響其他元素的哈希值,增加了誤判率。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-714718.html

到了這里,關(guān)于如何在十億級(jí)別用戶中檢查用戶名是否存在?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 如何修改git用戶名

    如何修改git用戶名

    首先在任意位置選擇Git Bash Here 在命令窗口輸入相關(guān)命令 1. 查看當(dāng)前git的用戶名 或者 2. 查看當(dāng)前git密碼 3. 查看git郵箱地址 4. 修改git用戶名 5. 修改git郵箱 6. 修改git密碼

    2024年02月15日
    瀏覽(23)
  • 小程序如何獲取用戶名和頭像?

    微信小程序獲取頭像的基本方法是調(diào)用小程序自帶的API? wx.getUserProfile(),這也是小程序官方目前最推薦的做法。 但是為了避免用戶感到自己的隱私被自動(dòng)調(diào)取,小程序要求調(diào)用 getUserProfile() 必須是用戶主動(dòng)點(diǎn)擊請(qǐng)求才可以,因此可以在前端設(shè)置一個(gè)彈窗(或者其他的按鈕),

    2024年02月11日
    瀏覽(15)
  • 6、ES單機(jī)設(shè)置用戶名密碼、集群設(shè)置用戶名密碼、es-head登錄、如何去掉密碼

    6、ES單機(jī)設(shè)置用戶名密碼、集群設(shè)置用戶名密碼、es-head登錄、如何去掉密碼

    在配置文件中添加如下參數(shù)cat config/elasticsearch.yml: 關(guān)閉es服務(wù)如果服務(wù)啟動(dòng)(kill進(jìn)程id) 啟動(dòng)es服務(wù) 待服務(wù)啟動(dòng)完成,且能正常訪問(wèn)后,執(zhí)行 集群此時(shí)是啟動(dòng)狀態(tài) elasticsearch-head查看 通過(guò)瀏覽器查看 http://192.168.180.45:9200/_cat/nodes?v 進(jìn)入主節(jié)點(diǎn)的bin目錄下執(zhí)行 再次在bin目錄輸

    2024年04月26日
    瀏覽(43)
  • 如何修改C盤下的用戶名

    如何修改C盤下的用戶名

    由于裝系統(tǒng)的時(shí)候可以隨意取名,很多人可能起了個(gè)中文名,這在后面進(jìn)行開(kāi)發(fā)時(shí)可能面臨種種無(wú)厘頭、莫名其妙的問(wèn)題,所以最好改成英文用戶名。 搜索發(fā)現(xiàn)更改用戶名非常之麻煩,而且常常要做好重裝系統(tǒng)的準(zhǔn)備,搞錯(cuò)一步可能系統(tǒng)就廢了。不僅如此,大多數(shù)網(wǎng)上的方法

    2024年02月03日
    瀏覽(26)
  • 關(guān)于RabbitMQ如何增加用戶名,設(shè)置權(quán)限

    關(guān)于RabbitMQ如何增加用戶名,設(shè)置權(quán)限

    1.安裝erl和rabbitmq;這些都可以在網(wǎng)上找到,安裝完成之后,配置成服務(wù),將erl和mq配置到環(huán)境變量中去。 安裝方法可參考:在Windows下安裝RabbitMQ_rabbitmq在windows下安裝_羅馬蘇丹默罕默德的博客-CSDN博客 感謝大佬?。。?2.增加用戶和設(shè)置權(quán)限: 2.1進(jìn)入mq安裝文件夾,到sbin目錄,

    2024年02月06日
    瀏覽(22)
  • 如何更改git里的用戶名和郵箱

    ? ? 在git中修改用戶名和電子郵件很簡(jiǎn)單。當(dāng)你進(jìn)行g(shù)it commit時(shí),在每一次提交中都包含了提交的用戶名和電子郵件信息。這些信息被用來(lái)追蹤誰(shuí)提交了哪個(gè)代碼。因此,在git中修改這些信息非常重要。在這篇文章中,我們將探索如何在git中修改用戶名和電子郵件。 首先,讓

    2024年02月10日
    瀏覽(23)
  • git如何查看和修改用戶名和郵箱

    在Git中可以通過(guò)以下命令查看你的全局配置: 其中, git config 是Git配置命令, --global 是全局配置選項(xiàng), user.name 和 user.email 是我們要查看的配置項(xiàng)。執(zhí)行以上命令后,Git將會(huì)返回相應(yīng)的全局用戶名和郵箱信息。 如果你還沒(méi)有設(shè)置過(guò)全局用戶名和郵箱,在執(zhí)行以上命令后將會(huì)

    2024年02月09日
    瀏覽(35)
  • 如何查看/設(shè)置git的用戶名和密碼

    查看用戶名?: 查看密碼:? 查看郵箱:

    2024年02月11日
    瀏覽(34)
  • iPortal如何靈活設(shè)置用戶名及密碼的安全規(guī)則

    iPortal如何靈活設(shè)置用戶名及密碼的安全規(guī)則

    作者:yx 目錄 前言 一、配置文件介紹 1、passwordRules節(jié)點(diǎn) ?注意事項(xiàng): 2、usernameRules節(jié)點(diǎn) 二、應(yīng)用實(shí)例 1、配置文件設(shè)置 2、驗(yàn)證擴(kuò)展結(jié)果 三、結(jié)果展示 SuperMap iPortal提供了擴(kuò)展賬戶信息合規(guī)度校驗(yàn)規(guī)則的能力,您可以靈活定制滿足自身項(xiàng)目需求的用戶名、密碼合規(guī)度校驗(yàn)規(guī)則

    2024年02月03日
    瀏覽(22)
  • 關(guān)于電腦如何修改c盤user下的用戶名

    關(guān)于電腦如何修改c盤user下的用戶名

    1. 首先打開(kāi)注冊(cè)表,cmd輸入regedit,而后找到 計(jì)算機(jī)HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionProfilelist 修改user名 2. 而后打開(kāi)管理員模式,重啟電腦進(jìn)入管理員模式,將原先用戶名改成自己想要的用戶名稱 最后需要更改環(huán)境變量

    2024年02月12日
    瀏覽(21)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包