第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

根據(jù)參數(shù)在數(shù)據(jù)庫中查找固定數(shù)量的 RANDOM 用戶的最佳方法是什么?

根據(jù)參數(shù)在數(shù)據(jù)庫中查找固定數(shù)量的 RANDOM 用戶的最佳方法是什么?

有只小跳蛙 2023-03-02 16:36:04
我正在 Kotlin 中開發(fā) Spring Boot REST API。底層數(shù)據(jù)庫是 Postgresql,我正在使用 Spring Data JPA 進行數(shù)據(jù)庫訪問。我有一個名為“用戶”的表,其中有一些用戶數(shù)據(jù)。用戶屬性之一是“性別”。它可以具有以下兩個值之一:MALE 或 FEMALE。我想在我的應(yīng)用程序中有一個功能來找到我以前從未見過的特定性別的人的隨機數(shù)(例如 20)。我的意思是 - 假設(shè)我有一個表,我在其中存儲我已經(jīng)看到的用戶的 ID。所以現(xiàn)在,我想做的基本上是從 Users 表中獲取 20 個隨機用戶,其中性別為 MALE 并且 id 不在 [我看到的 ids 列表] 中。查詢的隨機性最初讓我創(chuàng)建了一個原生查詢:SELECT *  FROM users WHERE gender = :gender ORDER BY random() LIMIT :number但是,我意識到這可能非常低效,因為該order by random()部分將對整個表格進行排序(如果我選擇一種性別,則為表格的一半)。所以我的第二個想法是處理代碼中的隨機性。所以我決定調(diào)用 db 來計算用戶數(shù)量(以獲取最高的 id),然后生成一些 id 值,范圍從 0 到最高,過濾掉我看到的那些,然后從中獲取用戶數(shù)據(jù)庫 ID:val numberOfUsersInDatabase = userRepository.count()     val idsOfUsersVotedForBefore = voteService.findIdsOfUsersVotedFor(requestingUser.id!!)    val excludedIds = idsOfUsersVotedForBefore.plus(requestingUser.id)    val idsToFetch = random.longs(2*amountOfIds, 1L, numberOfUsersInDatabase)             .boxed()             .filter { num -> !excludedIds.contains(num) }             .limit(amountOfIds)             .collect(toSet())   val randomUsers = userRepository.findUsersByIds(idsToFetch)但在這種情況下,我無法知道隨機選擇的用戶的性別是什么,所以我不可能在進行數(shù)據(jù)庫調(diào)用之前按性別過濾結(jié)果。你能建議如何更好地解決這個問題嗎?
查看完整描述

4 回答

?
收到一只叮咚

TA貢獻1821條經(jīng)驗 獲得超5個贊

我并不完全熟悉 Kotlin 語言,但我會用 Java 寫出邏輯,希望它能很好地為您翻譯。

你的目標(biāo)是獲取 20 個單一性別,但在獲取它之前你無法弄清楚它是什么性別。因為我們已經(jīng)從數(shù)據(jù)庫中獲取了 20 行,所以我們可以獲取更多作為備用。

我們可以使用累積分布來計算我們實際需要的行數(shù),使用這個工具:https://stattrek.com/online-calculator/binomial.aspx

假設(shè) 50/50 性別細(xì)分,概率為 0.5。如果您的性別分布與您的需求不同,您可以調(diào)整此項。如果性別細(xì)分不是 50/50,您可以為每個性別創(chuàng)建單獨的桶提取以獲得適當(dāng)?shù)某晒λ?。我們希望至少?20 場成功的比賽。

樣本大小為 60,我們有99.6% 的概率有 20 次或更多的性別匹配。

所以我們可以獲取 60 個而不是 20 個,篩選出所選性別的前 20 個。如果我們沒有達到 20(0.4% 的機會),則重新繪制另一組 20 來填充我們的組。所以 99% 的時間,60 行提取,在一個壞的情況下,可能是 80 行提取。這消除了在應(yīng)該適用于超大型數(shù)據(jù)庫的數(shù)據(jù)庫端使用 RAND 的情況。

Set<Long> idsToFetch = random.longs(2*amountOfIds, 1L, numberOfUsersInDatabase)

            .boxed()

            .filter { num -> !excludedIds.contains(num) }

            .limit(amountOfIds * 3)

            .collect(toSet());


List<User> randomUsers = userRepository.findUsersByIds(idsToFetch);


List<User> selectedUsers = randomUsers

                            .stream()

                            .filter(e -> e.gender == selectedGender)

                            .limit(amountOfIds)

                            .collect(toList());



if(selectedUsers.length < amountOfIds) { 

    //redo or single fetch operation

}


查看完整回答
反對 回復(fù) 2023-03-02
?
白衣染霜花

TA貢獻1796條經(jīng)驗 獲得超10個贊

在你的條件下選擇10萬個id.內(nèi)存中大約幾MB的數(shù)據(jù).just shuffle it.thenselect * from tables in(id1,id2...,id20)



查看完整回答
反對 回復(fù) 2023-03-02
?
江戶川亂折騰

TA貢獻1851條經(jīng)驗 獲得超5個贊

在您的帖子中使用查詢的物化視圖怎么樣。它可以安排在您選擇的時間表刷新(使用 cron 作業(yè)或 Postgres 提供的其他工具)



查看完整回答
反對 回復(fù) 2023-03-02
?
肥皂起泡泡

TA貢獻1829條經(jīng)驗 獲得超6個贊

不要生成 id,而是生成行索引。


然后在一個循環(huán)中你可以這樣做


select top 1 start at :randomBase *

from users where gender = :gender


查看完整回答
反對 回復(fù) 2023-03-02
  • 4 回答
  • 0 關(guān)注
  • 151 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號