提高去重計數(shù)效率——代理鍵+bitmap去重

# 背景

現(xiàn)實場景中經(jīng)常會遇到字符串字段去重計數(shù)的場景,常見方式如下:

- 最簡單的是count(distinct),性能最差,不推薦

- group by 后count(1),充分利用分布式并行計算的優(yōu)點,但是容易遇到數(shù)據(jù)傾斜,總體上是推薦

除了以上兩種方式,還可以借助rbm進行去重計數(shù),接下來介紹代理鍵+rbm的方法

# 方案介紹

rbm是bitset的優(yōu)化,把long型變量分為高32位和低32位分別存放,高32位用作索引(具體原理可參考https://blog.csdn.net/u011624157/article/details/108432494)。

rbm是很好用,但是只能存放int、long等數(shù)字類型,要對字符串做去重的話需要把字符串映射成數(shù)值,方案有兩種:

- 取hashcode,實現(xiàn)較簡單,但數(shù)據(jù)量太大會有hash碰撞,僅適用于中小規(guī)模數(shù)據(jù)量

- 使用row_number函數(shù)生成數(shù)字類型代理鍵,實現(xiàn)略復(fù)雜,需要做一個中間表,但是去重精確,適用于大數(shù)據(jù)量場景

## 詳細實現(xiàn)

接下來說代理鍵+rbm的詳細代碼

-? 1、先做代理鍵

```sql

select

? ? log_id,

? ? id

from(

select

? ? log_id,

? ? row_sequence() as id --使用row_sequence函數(shù)生成代理鍵

from(

select

? ? log_id

from

(

? ? select log_id

? ? from base_log

) t1

group by log_id

) a) a

distribute by id

;

```

- 2、根據(jù)rbm udaf進行去重

# 附:代理鍵名詞解釋

## 代理鍵

在關(guān)系型數(shù)據(jù)庫設(shè)計中,代理鍵(英語:surrogate key)是在當(dāng)資料表中的候選鍵都不適合當(dāng)主鍵時,例如資料太長,或是意義層面太多,就會請一個無意義的但唯一的字段來代為作主鍵。

代理鍵是:

Surrogate (1) – Hall, Owlett and Codd (1976)

一個代理鍵值確定了外部世界的一個實體。代理鍵值是數(shù)據(jù)庫生成的,從來不顯示給用戶或應(yīng)用程序看。

Surrogate (2) – Wieringa and De Jonge (1991)

一個代理鍵值確定了數(shù)據(jù)庫中的一個對象。代理鍵值是數(shù)據(jù)庫生成的,用戶或應(yīng)用程序看不到它。

在實踐中,代理鍵值通常是個自動遞增的數(shù)字。在Sybase或SQL Server,用identity column標(biāo)識代理鍵,PostgreSQL用serial,Oracle用SEQUENCE,在MySQL用標(biāo)記有AUTO_INCREMENT的字段。

## 何時使用代理鍵

以中華人民共和國的十八位身份證號為例,從左往右為六位數(shù)字地址碼,八位數(shù)字出生日期碼,三位數(shù)字順序碼和一位數(shù)字校驗碼。

一家公司想要將它的客戶記入數(shù)據(jù)庫,以客戶的身份證號作為主鍵當(dāng)然是可以的;但是這18位身份證號是用于標(biāo)識大陸13多億人口的,一家公司的客戶顯然沒有這么多,所以用18位的數(shù)字作為主鍵有點浪費空間。

另外,身份證號中包含了地區(qū)、生日信息,若以身份證號為主鍵,要不要另開字段記錄客戶的地區(qū)、生日也是個問題。如果不另開字段,從主鍵(身份證號)中提取地區(qū)、生日有點麻煩;如果開字段,主鍵和地區(qū)、生日字段的數(shù)據(jù)存在冗余。

所以,一般的做法是,根本不記錄客戶的身份證號(除非有其他需求),用一個代理鍵作為主鍵,另開字段記錄客戶的地區(qū)、生日等信息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容