網際網路使用者畫像,精準營銷,數倉有妙招
摘要:通過GaussDB(DWS)的Roaringbitmap功能,實現使用者畫像,精準營銷功能。
本文分享自華為雲社群《網際網路使用者畫像,精準營銷,GaussDB(DWS)來支招》,作者: fudgefactor。
目前在網際網路、教育、遊戲等行業都有實時精準營銷的需求。通過系統生成使用者畫像,在營銷時通過條件組合篩選使用者,快速提取目標群體。例如:
- 在電商行業中,商家在進行營銷活動前,需要根據活動的目的,圈選一批滿足特定特徵的目標使用者群體進行廣告推送。
- 在教育行業中,需要根據學生不同的特徵,推送有針對性的練習題目,幫助學生查漏補缺。
- 在搜尋、視訊、入口網站中,根據使用者關注的熱點,推送不同的內容。
這些業務場景都有一些共同的特點:
- 資料量龐大,運算量極大。
- 使用者規模龐大,標籤多,欄位多,佔用儲存空間也多。
- 圈選的特徵條件多樣化,很難找到固定索引,如果每個欄位一個索引,儲存空間又會暴增。
- 效能要求高,因為實時營銷要求秒級響應。
- 資料更新時效要求高,使用者畫像幾乎要求實時更新。
針對上述業務場景特點,GaussDB(DWS)的roaringbitmap可以高效生成、壓縮、解析點陣圖資料,支援最常見的點陣圖聚合操作(與、或、非、異或),滿足使用者在億級以上使用者、千萬級標籤的大資料量下實時精準營銷、快速圈選使用者的需求。
下面先通過兩個示例來理解Roaringbitmap在使用者畫像場景中的使用方法。
示例一:
假設有一張使用者瀏覽網頁的流水資訊表userinfo,表中的欄位如下:
CREATE TABLE userinfo (userid int, age int, gender text, salary int, hobby text )with (orientation=column);
userinfo表中的資料會隨著使用者資訊的變化不斷增長,同時,如果使用者有多個"愛好"(hobby),那麼就有多條記錄對應同一個userid。
假設要篩選出所有“收入大於10000元的男性,年齡大於30歲,愛好釣魚”的群體,向這些目標群體推送特定的訊息。
傳統的方法是直接在原表上執行查詢,語句如下:
select distinct userid from userinfo where salary > 10000 and age > 30 and gender ='m' and hobby ='fishing';
當userinfo表的資料量不大的時候,可以通過在salary, age, gender,hobby列上建立索引來滿足需求。但是如果userinfo表的資料量非常大,同時一張表的標籤數非常多(比如有100個屬性,需要對應有100個列)的時候,上述語句就不能滿足訴求,因為如下原因:
- 由於不確定會按照那些屬性做過濾,需要建立的索引會非常多。
- 求distinct的效能比較差。
這種場景下使用roaringbitmap就會有比較好的效果。
- 新建一張Roaringbitmap表:
CREATE TABLE userinfoset ( age int, gender text, salary int, hobby text, userset roaringbitmap, PRIMARY KEY(age,gender,salary,hobby) )with (orientation=column);
2. 所有userinfo表中的資料要通過標籤列聚合到userinfoset表中。可以採用對全量資料進行聚合的方法(如下命令所示)。
insert into userinfoset us select age, gender, salary, hobby, rb_build_agg(userid) from userinfo group by age, gender, salary, hobby;
3. 直接查詢userinfoset表獲得使用者篩選資訊。
select rb_iterate(rb_or_agg(userset)) from userinfoset where salary > 10000 and age > 30 and gender ='m' and hobby ='fishing';
資料進行聚合後的userinfoset的資料量相比源表小了很多,基表scan的效能會快很多,同時基於Roaringbitmap的優勢,計算rb_or_agg和rb_iterate的效能也很好,相比傳統的方法,效能明顯提升。
示例二:
由於DWS規格的限制,每張表最大可以有1600列,如果描述使用者的屬性有10000個,我們無法通過建立一個有10000列的表來實現這個方案,那麼示例一中的方案就不再有效了。
為此,我們可以這樣設計我們的表結構:
create table userinfoset ( tag_value_id int, userset roaringbitmap )with(orientation=column);
其中tag_value_id表示屬性值對應的id,比如,性別這一屬性,有”男“,”女“兩個值,我們可以把它編碼為1,2;學歷這個屬性的取值是”專科“,”本科“,”碩士“,“博士”,那麼分別編碼為3,4,5,6,等等。將不同的屬性值編碼為不同的id值。
userset列表示的是滿足tag_value_id所對應屬性值的使用者id的集合。比如tag_value_id=1這條記錄對應的userset就是所有性別為男的使用者的集合。
資料加工:
這個表的資料一般是需要通過加工得到的,假設原始資料的表結構如下(一共有10張表):
create table origin_1 ( userid int, tag_value_id1 int, tag_value_id2 int, tag_value_id3 int, ... tag_value_id998 int, tag_value_id999 int, tag_value_id1000 int )with(orientation=column); ... create table origin_10 ( userid int, tag_value_id9001 int, tag_value_id9002 int, tag_value_id9003 int, ... tag_value_id9998 int, tag_value_id9999 int, tag_value_id10000 int )with(orientation=column);
我們可以通過類似以下的語句將資料加工到目標表中:
insert into userinfoset select tag_value_id1, rb_build_agg(userid) origin_1 from origin group by tag_value_id1; ... insert into userinfoset select tag_value_id10000, rb_build_agg(userid) origin_10 from origin group by tag_value_id10000;
查詢:
假設需要圈選性別為男,學歷為本科的使用者的的個數有哪些,可以用以下語句實現:
select rb_or_cardinality_agg(userset) from userinfoset where tag_value_id in (1,4);
如果使用者要圈選的人群有更多的特徵,將對應的tag_value_id加入到in子句中即可。
如果想要知道這些使用者的具體的userid,可以通過如下函式實現:
select rb_iterate(rb_or_cardinality_agg(userset)) from userinfoset where tag_value_id in (1,4);
可以通過查詢產品手冊實現更加多樣化的人群圈選策略。