文章表500萬條資料,每天會有10萬條資料更新,從更新的10萬條中隨機選3000條做資料研究,如果做到高效?

來源:互聯網
上載者:User
題目是一道面試題
我的想法是另起一張表,存放今天更新的10萬條都有哪些;
我只想到這個第一步,接下來該怎麼做我還不知道怎麼去實現;
假設按我這樣的思路,我就算知道了每天更新的是哪10萬條資料,那我還是得去500萬條中找出3000條資料哦
不知道各位兄弟,有啥好的想法呢?

回複內容:

題目是一道面試題
我的想法是另起一張表,存放今天更新的10萬條都有哪些;
我只想到這個第一步,接下來該怎麼做我還不知道怎麼去實現;
假設按我這樣的思路,我就算知道了每天更新的是哪10萬條資料,那我還是得去500萬條中找出3000條資料哦
不知道各位兄弟,有啥好的想法呢?

10W中的3000條,機率是3%

那麼只要在儲存文章時,按照3%的機率,把本次更新文章儲存到緩衝中

這種緩衝用redis的set類型最好,set類型不會儲存重複的元素,所以文章反覆更新也不會在列表裡面產生多個結果

key的格式可以用"analyze:list:(Y-m-d)"

然後這個緩衝可以設定為48小時到期,如果有需要的話,每天可以拿前一天的緩衝歸檔到資料庫

考慮到隨機機率的誤差,可以把3%放大到5%,最後肯定會記錄得超過3000,但是也不會超太多,反正最後只拿3000條來用就行了

把每次更新都記錄起來的話,無論是記錄到緩衝還是資料庫,其實大部分的記錄是沒用的,不如按照機率先過濾一遍

其實記錄每條文章的update_time也可以,我覺得where update_time >= ? and update_time <= ? order by random() limit 3000差不多就行了,反正每天才跑一次而已,不過既然是面試的話,怎麼能不秀秀思路呢

優點:
1、沒有update_time欄位也能玩,對現有表結構無要求,給生產環境的資料庫加欄位是件麻煩事
2、萬一生產環境的資料庫負載比較高,order by random()查詢導致資料庫卡死也不好,這樣的話,最好是讀寫分離架構,在唯讀庫上查詢才行,產生了架構要求,我這個設計完全是個旁路記錄,除了redis之外沒要求
3、需要多少才記多少,額外IO少

一些粗陋的想法,僅供參考
分區
500萬條,為了方便。根據資料的更新時間進行資料庫分區(沒用過mysql分區的看這個,在文章後面講了),
比如說按照月份,我假設你這500萬條資料是一年的,那麼分成12份,每個區大約算42萬條記錄
這樣,當使用更新時間進行搜尋的時候,mysql就會根據你的更新時間 去選擇分區,
也就是被搜尋的資料是在這42萬條裡面去找(這肯定要比你在500萬裡面快多了,當然你要是按照天來分,那會更快)

加緩衝
這沒啥,就是你每天寫入mysql的時候取3000條資料寫入redis或者mongodb裡面,做研究就不從mysql裡面讀了。用php從緩衝裡面讀

多進程
你說的要做研究嘛,我假設你的研究演算法很複雜。你去學學swoole,開三個進程,一個進程處理1000個資料,最後匯總結果

  1. 取出當日更新的10萬

  2. id放入一個數組在數組中隨機取出3000個id

  3. 用select in讀取指定的3000條記錄

SELECT id FROM table WHERE date_refresh = 20120329SELECT * FROM table WHERE id IN (id_0, id_1, id_2, ..., id_2999)

https://www.zhihu.com/question/20151242

  • 首先,我會使用緩衝的方式,將每天更新的資料的主鍵 記錄下來。

  • 從緩衝中,隨機擷取3000主鍵

  • 拿著這3000 個主鍵,使用 IN 查詢,擷取對應的資料。

淺陋分析,勿笑。

1.擷取id區間

select max(id) as max_id, min(id) as min_id from (   select id from article_tb where update_time >= '2016-02-26 00:00:00') 

update_time有索引,id為自增長id
2.隨機擷取

select * from article_tb where id >= min_id and id < ( rand()*(max_id-min_id)+min_id ) limit 1

查詢3000次

// STEP 1 : 擷取當天文章ID區間// maxId -> select max(id) from news where 當天時間限定// minId -> select min(id) from news where 當天時間限定// STEP 2 : 取得隨機ID// 因為你一天有10萬資料,資料總量有很高// 所以避免使用MYSQL中的隨機$minId = 5000000;$maxId = 5100000;$i = 0;$resultIds = [];while(true){    $randId = rand($minId,$maxId);    if(in_array($randId, $resultIds)){        continue;    }        // 查詢驗證    // 根據你的需要驗證資料是否是審核的呀,是否是正常資料呀    // 如果正常就載入到結果數組中。    $resultIds[] = $randId;    $i++;        if($i==3000){        break;    }}// 到這裡結果已經有了// 可以儲存到結果集用其他方式分頁進行研究或者瀏覽。
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.