新增用戶:在某個時間段(一般為一整天)新登錄應(yīng)用的用戶數(shù),一般通過用戶設(shè)備號判斷用戶是否是第一次登錄應(yīng)用
次日留存率:(當天新增的用戶中,在注冊的第2天還登錄的用戶數(shù))/第一天新增總用戶數(shù)
公司有專門的統(tǒng)計數(shù)據(jù)庫,但是每張表的數(shù)據(jù)量都非常大,都是百萬、千萬級別,如果用常規(guī)的SQL語句去查找,查找的速度會非常慢,很不現(xiàn)實。結(jié)合實際的業(yè)務(wù),最后想到用Redis的集合去計算處理數(shù)據(jù)。
1、首先我們需要計算所有出現(xiàn)過的用戶設(shè)備號(SELECT distinct(user_device) FROM `statistic_20170801` UNION SELECT distinct(user_device) FROM `statistic_20170802`),把這些設(shè)備號存在redis的集合中($redis->sadd('user_device','6ab3d84ace678644f44645'));
2、再計算當天出現(xiàn)的所有設(shè)備號(SELECT distinct(user_device) FROM `statistic_20170803`),將這些設(shè)備號存在redis臨時集合中($redis->sadd('tmp_20170803','5a6vhbb84ace678fgv44f44645');
3、利用redis的sdiffstore命令,返回user_device和tmp_20170803兩個集合的差集($redis->sdiffstore('new_20170803',"user_device","tmp_20170803)),這個新的new_20170803集合,就是當日(20170803)的新增用戶,為避免占用內(nèi)存,需給這個new_20170803集合設(shè)置過期時間,由于要算次日留存率,所以new_20170803集合的生存期設(shè)為1天(同理,要算七日留存率,則設(shè)置7天生存期);
4、利用redis的SCARD命令,得出new_20170803這個集合的元素數(shù)量($redis->SCARD('new_20170803')),就是20170803新增的用戶數(shù)量;
5、不要忘記,將當天的用戶設(shè)備號合并進user_device集合中,利用redis的SUNIONSTORE命令,$redis->sunionstore('user_device',"user_device","tmp_20170803"),再用$redis->del('tmp_20170803'),刪除這個臨時集合;
6、計算次日留存率,我們要計算8月4日出現(xiàn)的所有設(shè)備號(SELECT distinct(user_device) FROM `statistic_20170804`),將這些設(shè)備號存在redis臨時集合中($redis->sadd('tmp_20170804','5a6vhbb84ace678fgv44f44645');
7、利用redis的SINTERSTORE命令,$redis->sinterstore('next_day_ retention',"new_20170803","tmp_20170804"),返回new_20170803和tmp_20170804兩個集合的并集,就是8月3日新增的用戶,8月4日也正常登陸的用戶集合了;
8、利用redis的SCARD命令,得出next_day_retention這個集合的元素數(shù)量($redis->SCARD('next_day_retention')),就是當天新增的用戶,在注冊的第2天還登錄的用戶數(shù);
9、之前給new_20170803這個集合設(shè)置一天的生存期就派上用場了,利用redis的SCARD命令,得出new_20170803這個集合的元素數(shù)量($redis->SCARD('new_20170803')),就是20170803新增的用戶數(shù)量;
10、再通過除法運算,$redis->SCARD('next_day_retention') / $redis->SCARD('new_20170803'),得出的就是8月3日的次日留存率了。