大數據去重方案

數據庫中有有一張表專門存儲用戶的維度數據,因爲隨着時間的推移,用戶的維度數據也可能發生變化,故每一次查看都會保存一次記錄。
如今須要對數據按用戶分析,但當中有大量的重複數據,僅用數據庫的等值去重明顯不可行。算法

對數據內容求MD5值

    MD5值的特色:
    1.壓縮性:任意長度的數據,算出的MD5值長度都是固定的。
    2.容易計算:從原數據計算出MD5值很容易。
    3.抗修改性:對原數據進行任何改動,哪怕只修改1個字節,所獲得的MD5值都有很大區別。
    4.強抗碰撞:已知原數據和其MD5值,想找到一個具備相同MD5值的數據(即僞造數據)是很是困難的。

根據MD5值的特色,對每條記錄的維度數據內容計算MD5值,而後根據MD5值判斷重複記錄。

對數據入庫以後利用sql直接查出重複數據,而後將重複數據移除或者標記。

至少在現階段內存和CPU的執行效率在固定時間內是有限的,大量的數據的查重和去重處理不可能同時在內存中進行。就像外部排序算法和內部排序算法差異很大,遇到此類大量數據查重問題對算法進行設計是有必要的。sql

布隆過濾器

布隆過濾器是一種採用hash法進行查重的工具。它將每一條數據進行n次獨立的hash處理,每次處理獲得一個整數,總共獲得n個整數。使用一個很長的數組表示不一樣的整數,每一次插入操做把這n個整數對應的位置的0設置爲1(若是已經被設置爲1則不變)。下次查找的時候通過一樣的計算,若是這幾個位置都是1則說明已經存在。

布隆過濾器的優勢是使用方便,由於並不將key存放進內存因此十分節省空間,多個hash算法無關,能夠併發執行效率高。缺點也是顯而易見的,這種算法是可能出現錯誤,有誤判率這種概念。經過hash的次數咱們能夠下降誤判率,可是不能保證沒有誤判的狀況。數據庫

BitMap

好比有2.5億個整數中找出不重複的整數的個數,內存空間不足以容納這2.5億個整數。

一個數字的狀態只有三種,分別爲不存在,只有一個,有重複。所以,咱們只須要2bits就能夠對一個數字的狀態進行存儲了,假設咱們設定一個數字不存在爲00,存在一次01,存在兩次及其以上爲11。那咱們大概須要存儲空間幾十兆左右。接下來的任務就是遍歷一次這2.5億個數字,若是對應的狀態位爲00,則將其變爲01;若是對應的狀態位爲01,則將其變爲11;若是爲11,,對應的轉態位保持不變。

最後,咱們將狀態位爲01的進行統計,就獲得了不重複的數字個數,時間複雜度爲O(n)。數組

hash分組

若是有兩份50G的數據,要查重,內存4G,怎麼查?

想法是先將50G的數據分別作hash%1000,分紅1000個文件,理論上hash作得好那麼這1000個文件的大小是差很少接近的。若是有重複,那麼A和B的重複數據必定在相對同一個文件內,由於hash結果是同樣的。將1000個文件分別加載進來,一一比對是否有hash重複。這種想法是先把全部數據按照相關性進行分組,相關的數據會處於一樣或者接近的位置中,再將小文件進行對比。

有1千萬條短信,找出重複出現最多的前10條?

能夠用哈希表的方法對1千萬條分紅若干組進行邊掃描邊建散列表。第一次掃描,取首字節,尾字節,中間隨便兩字節做爲Hash Code,插入到hash table中。並記錄其地址和信息長度和重複次數,1千萬條信息,記錄這幾個信息還放得下。同Hash Code且等長就疑似相同,比較一下。相同記錄只加1次進hash table,但將重複次數加1。一次掃描之後,已經記錄各自的重複次數,進行第二次hash table的處理。用線性時間選擇可在O(n)的級別上完成前10條的尋找。分組後每份中的top10必須保證各不相同,可hash來保證,也可直接按hash值的大小來分類。併發

使用數據庫創建關鍵字段(一個或者多個)創建索引進行去重

根據url地址進行去重:

使用場景:url地址對應的數據不會變的狀況,url地址可以惟一判別一條數據的狀況

思路:

  url存在Redis中

  拿到url地址,判斷url在Redis的集合中是否存在

    存在:說明url地址已經被請求過了,不在請求

    不存在:說明url地址沒有被請求過,請求,把該url地址存入Redis的集合中工具

布隆過濾器:

  使用多個加密算法加密url地址,獲得多個值

  往對應值的位置把結果設置爲1

  新來的一個url地址,同樣經過加密算法生成多個值

    若是對應位置的值全爲1,說明這個url地址已經被抓取過了

    不然沒有被抓取過,就把對應的位置的值設置爲1加密

根據數據自己進行去重:

  選擇特定的字段(可以惟一標識數據的字段),使用加密算法(MD5,sha1)將字段進行加密,生成字符串,存入Redis的集合中

  後續新來一條數據,一樣的方式進行加密,

    若是獲得的字符串在Redis中存在,說明數據存在,對數據進行更新,

    不然說明數據不存在,對數據進行插入。url

相關文章
相關標籤/搜索