通过分析用户的行为数据让更多的用户沉淀下来变成会员赚取更多的钱
质量分析: 在看中数量的同时需要关注流量的质量,即流量所能带来的价值
多维度细分: 维度指定是分析问题的角度,在不同的维度下,问题所展示的特性是不一样的
例如:
从页面的角度分析用户的行为轨迹
从转化目标分析,分析所谓的流失率或者转化率,层层递减逐级流失的描述模型
按照数据的流转流程进行,就是数据从哪里来到哪里去
js和html页面耦合在一起 不利于后续js维护
把js单独提取变成一个文件 然后通过src属性引入页面 进行所谓解耦合
一台服务器身兼多职 压力过大 降低服务器请求压力
单独的去部署服务器 专门用于采集数据的请求响应
可能会产生跨域问题(限制js跨域的数据发送)
以请求图片的形式 把采集的数据拼接成为图片的参数 发送到指定的服务器上去 绕开js跨域问题
通常在收集数据之前结合业务需求分析 分析需求确定收集的信息有哪些字段和收集途径
本来埋点代码的逻辑就是真正进行数据收集的逻辑,但是为了后续维护方便 把真正收集数据的js提取出变成js文件,在这种情况下,埋点代码就变成了如何把这个js文件引入到页面上
1.直接通过src属性引入
2.js匿名函数自调用
创建匿名函数,自己调用自己并且只调用一次 通常用于页面的初始化操作
所谓后端就是接受解析前端发送采集数据的服务器
注意搞清楚 nginx中location模块的具体职责:用于请求url资源路径的匹配
考虑日志中字段之间的分隔符问题,以后有利于程序处理数据方便
常见的分隔符 制表符 空格 特殊符号 \001
nginx默认把日志一直写在一个文件中access.log 不利于后续的维护移动操作处理
通过shell脚本给nginx进程发送usr1信号 告知其重载配置文件 在重载配置文件的时候 重新打开一个新的日志文件 在配合crontab定时器 从而完成间接的通过时间配置文件的滚动
注 :tomcat默认对外发布服务的路径是/var/www/html
nginx默认网址路径是 /usr/local/nginx/html/
在使用mr编程的过程中牢牢把握住key是什么 因为mr中key有很多默认的属性
分区-->key 哈希 % reducetasknums
分组-->key相同的分为一组
排序-->按照key的字典序排序
以维度为标准,开展数据的分析需求
适用于面向分析领域的理论,比如分析型数据库,数据仓库 数据集市
分析主题的客观事件度量 是分析主题的数据聚集 试试表中一条记录往往对应的客观的一个时间,往往是一堆主键的聚集
所谓的维度表就是看待问题的角度 可以通过不同的维度去分析一个事实表 得出不同的分析结果 维度表可以跟事实表进行关联查询
Q:点击流模型数据算什么类型的表?
点击流模型数据既不是事实表 也不是维度表 是一个业务模型数据 可以称为事实表的业务延伸
所谓的多维度数据分析就是指通过不同维度的聚集计算出某种度量值
常见度量值:max min count sum avg topN
举个例子:统计来自北京女性24岁未婚的过去三年购物金额最多的三个。
维度可以分为: 地域 性别 年龄 婚姻 时间
度量值:sum (订单金额)--->top3
星型模式
一个事实表多个维度表,维度表之间没有关系 维度表跟事实表进行关联 企业数仓发展初期常见的模型
雪花模式
一个事实表多个维度表 维度表可以继续关联维度表 但是不利于后期的维护 企业中尽量避免演化该模型
星座模式
多个事实表 多个维度表 某些维度表可以共用 企业数仓发展中后期常见的模型
事实表:对应着数据预处理之后的原始网站日志情况
维度表:通常要结合业务决定分析的维度 要和事实表能够关联上 要以能够涵盖事实表位基本标准
load data local inpath'/root/hivedata/part-m-00000' into table ods_weblog_origin partition(datestr = "20231201") ;
点击流模型之pageviews表
load data local inpath'/root/hivedata/part-r-00000' into table ods_click_pageviews partition(datestr = "20231201") ;
点击流模型之visit
load data local inpath'/root/hivedata/part-r-00000' into table ods_click_stream_visitpartition(datestr = "20231201") ;
时间维度表数据
load data local inpath'/root/hivedata/dim_time.dat' into table t_dim_time ;
宽表窄表的引入
为了分析方便,可以事实表中的一个字段切割提取多个属性出来构成新的字
段,因为字段变多了,所以称为宽表,原来的成为窄表。
又因为宽表的信息更加清晰明细,所以也可以称之为明细表。
宽表的实现
1.宽表的数据由何而来: 由原始窄表得到
2.宽表需要扩宽哪些字段:由业务而定
3.使用什么技术扩宽字段:insert into 宽名 select from 窄名 插入什么语句取决于返回的结果,所以查询的时候就需要使用hive语句进行拓宽操作
简单的拓宽可以使用字段截取:
select substring(time_local,6,2)as month from ods_weblog_origin limit 1;
来源url的高级拓宽:
select a.*,b.*
from ods_origin a
LATERAL VIEW parse_url(regexp_replace(http_referer,"\"",""),
'HOST','PATH','QUERY','QUERY:id') b as host,path,query,query_id;
基础指标:
一些比较单一的指标,很容易判断理解如
pv:页面的加载总次数
uv:独立访客数
vv:会话次数
复合指标:
在基础指标之上,通过一些简单的计算产生的指标如
1.平均访客次数:一天之内人均会话数==总的会话次数(session)/总的独立访客数=vv/uv
2.平均访问深度:一天之内人均浏览页面数==总的页面浏览数/总的独立访客数==pv/uv
3.平均会话时长:平均每次会话的停留时长==总的会话停留时长./会话次数
4.首页跳出率:访问网站且该页面是首页/总的访问次数
select
count (*)
from dw_weblog_detail t where t.datestr="20181101" and t.valid="true";
select
count(distinct remote_user)as uv
from dw_weblog_detail t where t.datestr="20181101";
select
count(t.session) as vv
from ods_click_stream_visit t where t.datestr="20181101";
select
count(distinct remote_user)as ip
from dw_weblog_detail t where t.datestr="20181101";
select
vv/uv
from dw_webflow_basic_info t where t.datestr="20181101";
--上述指标不符合客观规律
--原因:在计算基础指标的时候 uv使用的是宽表的数据 没有进行静态资源的过滤
--vv使用的是点击流模型的数据 在预处理阶段进行了静态资源的过滤
--一个采用过滤的一个采用未过滤的 计算的指标不合法
--解决方法 统统采用过滤后的静态资源进行计算 ods_click_stream_visit
select
count(t.session)/count(distinct t.remote_addr)
from ods_click_stream_visit t where t.datestr="20181101";
总的停留时长/会话的次数
select
sum(t.page_staylong)/count (distinct t.session)
from ods_click_pageviews t where t.datestr="20181101";
select
count (t.session)
from ods_click_stream_visit t where t.datestr="20181101" and where t.pagevisits=1 and t.inpage="/hadoop-mahout-roadmap";
多维数据分析
计算该处理批次一天内各小时的pv
select
t.hour,count(*) as pvs
from dw_weblog_detail t where t.datestr="20181101" group by t.hour;
计算每天的pvs
方式一:dw_pvs_everyhour_oneday 将每个小时的pvs进行sum求和
select sum(pvs) from dw_pvs_everyhour_oneday t where datestr="20181101";
方式二:dw_weblog_detail 直接基于宽表计算出每天的pvs
select count(*) from dw_weblog_detail where datestr="20181101";
方式三:如果数据不是分区表 直接根据day进行分组
select
t.month,t.day,count(*) as pvs
from dw_weblog_detail t where t.datestr="20181101" group by t.month ,t.day;
sql:
insert into table dw_pvs_everyday
select count(*) as pvs,a.month as month,a.day as day from (select distinct month, day from t_dim_time) a
join dw_weblog_detail b
on a.month=b.month and a.day=b.day
group by a.month,a.day;
拓展:使用维度表关联的方式计算每个小时的pvs
sql:
insert into table dw_pvs_everyhour
select count(*) as pvs,a.month as month,a.day as day,a.hour as hour from (select distinct month, day,hour from t_dim_time) a
join dw_weblog_detail b
on a.month=b.month and a.day=b.day and a.hour=b.hour
group by a.month,a.day,a.hour;
按照来访维度,时间维度分析
统计每小时,各来访url产生的pv量
insert into table dw_pvs_referer_everyhour partition(datestr='20181101')
select http_referer,ref_host,month,day,hour,count(1) as pv_referer_cnt
from dw_weblog_detail
group by http_referer,ref_host,month,day,hour
having ref_host is not null
order by hour asc,day asc,month asc,pv_referer_cnt desc;
统计每小时,各来访host的产生的pv数并排序
select ref_host,month,day,hour,count(1) as ref_host_cnts
from dw_weblog_detail
group by ref_host,month,day,hour
having ref_host is not null
order by hour asc,day asc,month asc,ref_host_cnts desc;
统计每小时各来访host的产生pvs数最多的前N个
select t.hour,t.od,t.ref_host,t.ref_host_cnts from
(select ref_host,ref_host_cnts,concat(month,day,hour) as hour,
row_number() over (partition by concat(month,day,hour) order by ref_host_cnts desc) as od
from dw_pvs_refererhost_everyhour) t where od<=3;
例如:
SELECT
count(sex) as nums
FROM (SELECT
a.*,b.*
FROM a join b on a.id=b.id
where ...
)t
where t.city="beijing"
group by t.sex
HAVING t.sex is not NULL
order by nums DESC limit 10 ;
-- 在编写select查询语句时 select确定之后要立马去寻找from关键字 因为后面跟的急速操作的表
--表可能是真实存在的表 如果是真实存在的表 那么直接使用
--表也可能不存在 设法通过查询把这个表查询出来 基于这个虚拟的表进行操作
--只有表确定之后 在结合业务确定返回的字段或者表达式
-- 嵌套子查询,先执行里面的查询语句 后执行外面的查询语句
select
t.request,count(*) as pv
from dw_weblog_detail t where t.datestr="20181101" group by t.request having
t.request is not null order by pvs desc limit 10;
select
t.hour, t.remote_addr,count(*)as pv
from dw_weblog_detail t where t.datestr="20181101" group by t.hour , t.remote_addr
order by t.hour ,pv desc
--今天 (根据今天收集的数据进行去重统计)
select
distinct t.remote_addr as ip
from dw_weblog_detail t where t.datestr="20181101";
--历史
create table dw_user_dsct_history(
day string,
ip string
)
partitioned by(datestr string);
--框架
select
今天.ip
from 今天 left join 历史 on 今天.ip = 历史.ip
where 历史.ip is null;--新访客
select
今天.ip
from 今天 left join 历史 on 今天.ip = 历史.ip
where 历史.ip is not null;--老访客
访问次数大于一就叫回头访客
--先计算每个用户产生的会话数
select
t.remote_addr,count(t.session) as num
from ods_click_stream_visit t where t.datestr="20181101" group by t.remote_addr;
--方式一 采用嵌套查询的思路
select
from(
select
from ods_click_stream_visit t where t.datestr="20181101" group by t.remote_addr) a
where a.nums=1; --单次访客
select
from(
select
from ods_click_stream_visit t where t.datestr="20181101" group by t.remote_addr) a
where a.nums > 1; --回头访客
--方式二:采用having
select
t.remote_addr,count(t.session) as num
from ods_click_stream_visit t where t.datestr="20181101" group by t.remote_addr
having nums >1 --回头访客;
全量数据:所有的数据全部的数据
增量数据:从上次开始到当下中间新增的数据
hive-->hdfs
insert overwrite directory '/weblog/export/dw_pvs_referer_everyhour' row format delimited fields terminated by ',' STORED AS textfile select referer_url,hour,pv_referer_cnt from dw_pvs_referer_everyhour where datestr = "20181101";
bin/sqoop export \
--connect jdbc:mysql://node03:3306/weblog \
--username root --password 123456 \
--table dw_pvs_referer_everyhour \
--fields-terminated-by '\001' \
--columns referer_url,hour,pv_referer_cnt \
--export-dir /weblog/export/dw_pvs_referer_everyhour
hdfs----->mysql
bin/sqoop export \
--connect jdbc:mysql://node03:3306/weblog \
--username root \
--password 123456 \
--table dw_webflow_basic_info \
--fields-terminated-by '\001' \
--update-key monthstr,daystr \
--update-mode allowinsert \
--export-dir /user/hive/warehouse/itheima.db/dw_webflow_basic_info/datestr=20181103/
手动导入增量数据方法
insert into table dw_webflow_basic_info partition(datestr="20181104") values("201811","04",10137,1129,1129,103);
shell脚本定时增量导入
#!/bin/bash
export SQOOP_HOME=/export/servers/sqoop
if [ $# -eq 1 ]
then
execute_date=`date --date="${1}" +%Y%m%d`
else
execute_date=`date -d'-1 day' +%Y%m%d`
fi
echo "execute_date:"${execute_date}
table_name="dw_webflow_basic_info"
hdfs_dir=/user/hive/warehouse/itheima.db/dw_webflow_basic_info/datestr=${execute_date}
mysql_db_pwd=123456
mysql_db_name=root
echo 'sqoop start'
$SQOOP_HOME/bin/sqoop export \
--connect "jdbc:mysql://node03:3306/weblog" \
--username $mysql_db_name \
--password $mysql_db_pwd \
--table $table_name \
--fields-terminated-by '\001' \
--update-key monthstr,daystr \
--update-mode allowinsert \
--export-dir $hdfs_dir
echo 'sqoop end'
业务目标完成会包含各个不同的步骤 步骤之间或者步骤内部往往存在依赖关系,甚至需要周期性重复性执行,这时候就需要设定工作流 知道工作按照设定的流程进行
预处理模块的任务调度
数据入库的调度
shell脚本编写
如何使用azkaban调度hive
何谓数据可视化
又称之为数据报表展示,属于数据应用中的一种,尽量使用图形表格的形式把分析的结果展示给被人看。
数据可视化的大量工作属于前端开发 我们需要掌握的是如何把数据分析处理 已经把数据按照要求传递给可视化的软件。
数据可视化是一种锦上添花的事。核心还是数据分析的过程。
echarts简单入门
在页面上引入echarts.js
在页面创建一个dom容器 有高有宽的范围
选择容器使用echarts api创建echarts 实例
var myChart = echarts.init(document.getElementById('main'));
根据业务需求去echarts官网寻找对应的图形样式 复制其option
var option = { title: { text: 'ECharts 入门示例' }, tooltip: {}, legend: { data:['销量'] }, xAxis: { data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] };
把option设置到创建的echarts 实例中
// 使用刚指定的配置项和数据显示图表。 myChart.setOption(option);
对我们来说需要思考如何把数据从后端动态加载返回至前端页面进行可视化展示。
数据可视化后端web工程
职责:把导出在mysql中的数据按照前端需要的格式查询返回给前端
技术: php java 本项目使用javaEE 基于SSm做数据查询
mybatis逆向工程
可以根据对应的数据库表你想生成与之对应的javabean mapper sql
最重要的是提供了一个所谓的example类 该类用于条件封装 满足与sql的增删改查操作
当业务简单 不实际多表操作的时候 可以直接使用逆向工程 是的dao层代码量降为零。