这三个数据基本反应了 产品 运营情况
新增一般反应一个产品的市场拓展能力,是活水涌入。
活跃是收入的主要来源
留存一般指新增留存(也有活跃留存),新增用户第n天后任然活跃的人数,有1日后留存,2日后留存,n日后留存。它反应了忠诚度。也反应了新增用户有多少是不理智的增加(类似股票第一日不理智追高买入,次日抛售形成缺口---补缺)
用户有两个表示法:设备和账户。
统计基于某个纬度,这个纬度可以是:总体、渠道(channel)、版本(version)等。
所以有总体新增、渠道新增、版本新增等,活跃和留存也是一样。
如果一个产品下面有多个子产品,纬度又更加复杂,如子产品1的渠道1的新增等等。
对于表设计方面,临时表只需要[first use date] 和 [last use date] 2个字段 和 某纬度字段,就能计算出某纬度下的新增、活跃、留存。其中,临时表中 [last use date] 是upsert(update if exist else insert)的。[first use date]=今天,就是今天的新增; [last use date] =今天,就是今天的日活;[first use date]=20150827 and [last use date] =20150828,这样就算出了20150827的次日留存数,20150827的次日留存率=20150827的次日留存数/20150827的新增。因为 [last use date]是不断更新的,所以要注意活跃和留存的计算时机。临时表是全量的,各维度要加索引
=====
之前用的是mysql,优点是便于理解,便于计算
缺点是 当主键<用户标识, 纬度>组合过大时,mysql的临时中间表因为索引的关系,插入会很慢;并且数据出错,重新跑临时中间表会需要很长时间。
可以考虑列存储
现在选用的是 aws的DynamoDB,也可以自己搭建HBase
主键是用户标识(这里假定是aid),一天一列,当天用户活跃 就把当天这一列置为1
存储格式如下
pk 20160101 20160102 20160103 20160104
uid1 1 1
uid2 1 1
uid3 1 1
文档类型doc写法如下
[{"id": "uid1", "20160101": 1, "20160103":1},
{"id": "uid1", "20160102": 1, "20160104":1},
{"id": "uid1", "20160102": 1, "20160104":1}]
(可以看出,处理压力只有用户增长成线性关系,所以增长压力不大)
然后遍历所有行(可以分布式遍历,分批读取遍历)
for line in doc:
ymds = line.keys() 然后过滤掉非日期字段
aid = 主键
if 某天= min(ymds):
某天新增 +1
if 某天 in ymds:
某天活跃 +1