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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

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

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

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

4 回答

?
收到一只叮咚

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊

我并不完全熟悉 Kotlin 語(yǔ)言,但我會(huì)用 Java 寫(xiě)出邏輯,希望它能很好地為您翻譯。

你的目標(biāo)是獲取 20 個(gè)單一性別,但在獲取它之前你無(wú)法弄清楚它是什么性別。因?yàn)槲覀円呀?jīng)從數(shù)據(jù)庫(kù)中獲取了 20 行,所以我們可以獲取更多作為備用。

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

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

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

所以我們可以獲取 60 個(gè)而不是 20 個(gè),篩選出所選性別的前 20 個(gè)。如果我們沒(méi)有達(dá)到 20(0.4% 的機(jī)會(huì)),則重新繪制另一組 20 來(lái)填充我們的組。所以 99% 的時(shí)間,60 行提取,在一個(gè)壞的情況下,可能是 80 行提取。這消除了在應(yīng)該適用于超大型數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)端使用 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

}


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

TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超10個(gè)贊

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



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

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超5個(gè)贊

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



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

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超6個(gè)贊

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


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


select top 1 start at :randomBase *

from users where gender = :gender


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

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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