一、商业BI系统概述

商业智能系统,通常简称为商业智能系统,是商业智能软件的简称,是为提高企业经营绩效而采用的一系列方法、技术和软件的总和。通常被理解为将企业中的现有数据转换为知识并帮助企业做出明智的业务决策的工具。

BI系统中的数据来自企业的其他业务系统。例如,一个面向业务的企业,其业务智能系统数据包括业务系统订单、库存、交易账户、客户和供应商信息,以及企业所属行业和竞争对手的数据,以及其他外部环境数据。这些数据可能来自于CRM、SCM和发票等业务系统。

商业BI系统的组成部分:

  • 数据仓库:首先,需要收集所有的数据。这个过程称为“数据仓库”。数据仓库提供了一个数据存储环境,从多个数据源获取的数据根据特定的主题进行ETL(提取、转换、转储)数据、清理数据和存储。
  • OLAP:其次,需要数据分析来辅助企业建模的能力。OLAP是一种基于数据仓库环境的数据分析工具。OLAP解决了基于OLTP分析的多维度分析效率低的缺点。在实际应用中,数据挖掘也常用来挖掘过去和预测未来。它是一个使用知识发现工具来挖掘以前未知的和潜在有用的知识的过程。它是一种主动的自动发现方法。
  • BI看板:商业智能的一个重要特性是数据可视化。数据可视化是指通过适当的图表类型以一种视觉上吸引人的方式显示信息,使每个人都能更快更好地理解数据。另外,BI还有终端信息查询和报表生成功能。
  • 到这里,所有的流程就被称为“BI系统”。

二、项目背景

1、直接用Mysql做数据分析缺陷

受互联网+概念的催化,教育市场发展火热,越来越多的教育机构和平台不断涌现,包括有线上学习和线下培训,K12教育和职业教育等,那些注重用户服务、教育质量的平台会最终胜出。目前的企业痛点:

  1. 数据量大,现有MySQL业务数据库直接读取模式不能满足业务统计性能、效率需要;
  2. 系统多、数据分散,缺少从营销、咨询、报名、教学等等完整业务环节的数据贯通;
  3. 统计分析难度高、工作量大。缺少元数据、数据集合的规范存储,业务部门有数据分析角度需求时,需要程序员、DBA突击查数据、做报表,尤其年底各个部门排队等DBA协助出数据;

如何提高用户服务水平,提高教育质量是每个机构都面临的问题。信息的共享和利用不充分,就导致尽管学校多年的信息化应用积累了大量的数据,但信息孤岛的壁垒一直没有打破,对这些数据无法进一步的挖掘、分析、加工、整理,不能给学校教育、教学、研发、总务等各方面管理决策提供科学、有效的数据支撑。

2、大数据技术的应用

大数据技术的应用可以从海量的用户行为数据中进行挖掘分析,根据分析结果优化平台的服务质量,最终满足用户的需求。

教育大数据分析平台项目就是将大数据技术应用于教育培训领域,为企业经营提供数据支撑:

  1. 建立集团数据仓库,统一集团数据中心,把分散的业务数据进行预先处理和存储
  2. 根据业务分析需要,从海量的用户行为数据中进行挖掘分析,定制多维的数据集合,形成数据集市,供各个场景主题使用
  3. 前端业务数据展示选择和控制,选取合适的前端数据统计、分析结果展示工具

三 、数据仓库+OLAP:“访问客户量” 大数据分析

1、需求分析

目的: 分析每一个调研需求需要计算什么指标, 以及计算这个指标需要通过那些维度,而且还包括计算这个需求涉及到哪些表和哪些字段。

客户访问和咨询主题,顾名思义,分析的数据主要是客户的访问数据和咨询数据。但是经过需求调研,这里的访问数据,实际指的是访问的客户量,而不是客户访问量。原始数据来源于咨询系统的mysql业务数据库。

用户关注的核心指标有:

  • 1、总访问客户量;
  • 2、地区独立访客热力图;
  • 3、访客咨询率趋势;
  • 4、客户访问量和访客咨询率双轴趋势;
  • 5、时间段访问客户量趋势;
  • 6、来源渠道访问量占比;
  • 7、搜索来源访问量占比;
  • 8、活跃页面排行榜;

1.1 需求1: 统计指定时间段内,访问客户的总数量。能够下钻到小时数据

说明:统计指定时间段内,访问客户中各区域人数热力图。能够下钻到小时数据。
展现:地图热力图
指标:按照地区聚合访问的客户数量
维度:年、季度、月
粒度:天
条件:年、季度、月
数据来源:咨询系统的web_chat_ems_2019_12等月表

按年:显示指定年范围内每天的客户访问量
按季度:显示指定季度范围内每天的客户访问量
按月:显示指定月份范围内每天的客户访问量

指标: 访问量
维度: 时间维度:  年 季度 月 天  小时
涉及到哪些表: web_chat_ems_2019_12涉及到哪些字段: 时间维度:  create_time说明: 发现create_time字段中包含有年 月 天 小时这些数据, 此时可以认为一个字段中涵盖了多个字段的数据处理方式: 后期需要对此字段进行转换处理工作将create_time  转换为:  yearinfo  monthinfo  dayinfo  hourinfo ....指标字段: sid说明: 指标计算的逻辑 先对sid进行去重操作, 然后统计个数过程

1.2 需求2: 统计指定时间段内,访问客户中各区域人数热力图。能够下钻到小时数据

说明:统计指定时间段内,访问客户中各区域人数热力图。能够下钻到小时数据。
展现:地图热力图
指标:按照地区聚合访问的客户数量
维度:年、季度、月
粒度:天
条件:年、季度、月
数据来源:咨询系统的web_chat_ems_2019_12等月表

按年:显示指定年范围内每天的客户访问量
按季度:显示指定季度范围内每天的客户访问量
按月:显示指定月份范围内每天的客户访问量

指标:  访问量
维度:时间维度:  年 季度 月 天  小时区域维度:
涉及到哪些表:  web_chat_ems_2019_12涉及到哪些字段:时间维度: create_time区域维度: area指标字段: sid

1.3 需求3: 统计指定时间段内,不同地区(省、市)访问的客户中发起咨询的人数占比

说明:统计指定时间段内,不同地区(省、市)访问的客户中发起咨询的人数占比;
咨询率=发起咨询的人数/访问客户量;客户与网咨有说一句话的称为有效咨询。
展现:线状图
指标:访客咨询率
维度:年、月、城市
粒度:天
条件:年、季度、月、省、市
数据来源:咨询系统的web_chat_ems_2019_12等月表

按年:显示指定年范围内每天的客户访问量
按季度:显示指定季度范围内每天的客户访问量
按月:显示指定月份范围内每天的客户访问量

占比计算: 统计出每个地区的总访问量 和 每个地区发起咨询的人数之间比例

指标: 访问量  和 咨询量
维度:时间维度: 年 季度 月 天  小时区域维度
说明: 访问量的统计可以直接复用需求2的结果即可, 此处可以省略
涉及到哪些表: web_chat_ems_2019_12涉及到哪些字段: 时间维度: create_time区域维度: area咨询量判断:  msg_count >= 1 即可指标字段: sid咨询量指标计算:先对数据进行过滤得出咨询数据, 然后通过先去重 在求个数过程

1.4 需求4: 统计指定时间段内,每日客户访问量/咨询率双轴趋势图。能够下钻到小时数据。

说明:统计指定时间段内,每日客户访问量/咨询率双轴趋势图。能够下钻到小时数据。
每日客户访问量可以复用指标2数据;
咨询率可以复用指标3的数据。

按年:显示指定年范围内每天的客户访问量
按季度:显示指定季度范围内每天的客户访问量
按月:显示指定月份范围内每天的客户访问量

指标: 访问量   和 咨询量
维度:时间维度: 年 季度 月 天  小时
说明: 访问量的统计可以直接复用需求1的结果即可涉及到哪些字段: 时间维度:  create_time说明: 发现create_time字段中包含有年 月 天 小时这些数据, 此时可以认为一个字段中涵盖了多个字段的数据处理方式: 后期需要对此字段进行转换处理工作将create_time  转换为:  yearinfo  monthinfo  dayinfo  hourinfo ....指标字段: sid说明: 指标计算的逻辑 先对sid进行去重操作, 然后统计个数过程添加一个咨询数据过滤的条件:msg_count >= 1 即可

1.5 需求5: 统计指定时间段内,1-24h之间,每个时间段的访问客户量。

说明:统计指定时间段内,1-24h之间,每个时间段的访问客户量。
横轴:1-24h,间隔为一小时,纵轴:指定时间段内同一小时内的总访问客户量。
展现:线状图、柱状图、饼状图
指标:某小时的总访问客户量
维度:天
粒度:区间内小时段
条件:天
数据来源:咨询系统的web_chat_ems_2019_12等月表

指标: 访问量
维度:时间维度 : ....
此需求的结果 在需求1中 已经涵盖了, 不需要再次分析

1.6 需求6: 统计指定时间段内,不同来源渠道的访问客户量占比。能够下钻到小时数据。

说明:统计指定时间段内,不同来源渠道的访问客户量占比。能够下钻到小时数据。
展现:饼状图
指标:比值
维度:年、季度、月
粒度:天
条件:年、季度、月
数据来源:咨询系统的web_chat_ems_2019_12等月表

按年:显示指定年范围内每天的客户访问量
按季度:显示指定季度范围内每天的客户访问量
按月:显示指定月份范围内每天的客户访问量

  • 理解1: 占比 指的是各个来源渠道的访问量 和 总访问量的占比情况
  • 理解2: 占比 指的是 各个来源渠道中, 访问量 和 咨询量之间占比情况 (按此理解走)
指标: 访问量  和 咨询量
维度:时间维度:  年 季度 月  天 小时来源渠道维度
涉及到哪些表: web_chat_ems_2019_12
涉及到哪些字段:时间维度: create_time来源渠道维度:  origin_channel指标字段:  sid

1.7 需求7: 统计指定时间段内,不同搜索来源的访问客户量占比。能够下钻到小时数据。

说明:统计指定时间段内,不同搜索来源的访问客户量占比。能够下钻到小时数据。
展现:饼状图
指标:比值
维度:年、季度、月
粒度:天
条件:年、季度、月
数据来源:咨询系统的web_chat_ems_2019_12等月表

按年:显示指定年范围内每天的客户访问量
按季度:显示指定季度范围内每天的客户访问量
按月:显示指定月份范围内每天的客户访问量

  • 理解1: 占比 指的是不同搜索来源的访问量 和 总访问量的占比情况 (按此理解走)
  • 理解2: 占比 指的是 不同搜索来源中, 访问量 和 咨询量之间占比情况
指标:   访问量
维度:时间维度 :  年 季度 月  天 小时搜索来源渠道维度
涉及到哪些表: web_chat_ems_2019_12
涉及到那些字段: 时间维度: create_time搜索来源维度字段: seo_source指标字段: sid

1.8 需求8: 统计指定时间段内,产生访问客户量最多的页面排行榜TOPN。能够下钻到小时数据。

说明:统计指定时间段内,产生访问客户量最多的页面排行榜TOPN。能够下钻到小时数据。
展现:柱状图
指标:访问客户量
维度:页面、年、季度、月
粒度:天
条件:年、季度、月、Top数量
数据来源:咨询系统的 web_chat_text_ems_2019_11等月表

按年:显示指定年范围内每天的客户访问量
按季度:显示指定季度范围内每天的客户访问量
按月:显示指定月份范围内每天的客户访问量

指标:  访问量
维度: 时间维度: 年 季度 月  天 小时受访页面维度:
涉及到哪些表: web_chat_text_ems_2019_12
涉及到哪些字段: 时间维度: 暂不知道受访页面维度: from_url指标计算: 直接计算总数量

总结:

指标: 访问量
维度: 固有维度:  时间维度: 年 季度 月  天 小时产品属性维度:总访问量地区维度来源渠道维度搜索来源维度受访页面维度
-------------------------------------
指标:  咨询量
维度:固有维度:  时间维度: 年 季度 月 天 小时产品属性维度:总咨询量地区维度来源渠道维度发现点: 不管计算咨询量还是访问量 都使用的同一个表, 至少咨询量比访问量在计算的时候多个一个条件:msg_count >=1涉及到表: web_chat_ems_2019_12 和  web_chat_text_ems_2019_12涉及到字段: web_chat_ems_2019_12:指标: sid (咨询量 和 访问量)说明: 先去重, 在统计个数过程时间维度: create_time地区维度: area来源渠道维度: origin_channel搜索来源维度: seo_sourceweb_chat_text_ems_2019_12:受访页面维度: from_url需求转换的点:create_time字段 后期需要进行转换操作

2. 数据初始准备工作

访问客户量的数据来源于咨询系统的访问会话月表web_chat_ems,表名的格式为web_chat_ems_年_月,年份为4位数字,月份为二位数字,如果为单数时,前面会用0来补全,比如web_chat_ems_2019_07。

web_chat_text_ems表是访问附属月表,表名的格式和web_chat_ems相同。web_chat_ems和web_chat_text_ems是一一对应的,通过主键id进行关联。

1、新建数据库:在业务库中, 构建 业务数据库: (MySQL) 请采用课件提供建库语句, 以免出现中文乱码问题

create database nev default character set utf8mb4 collate utf8mb4_unicode_ci;

2、执行相关的SQL的脚本, 将数据导入到nev数据库中



web_chat_ems表结构

create table web_chat_ems_2019_07
(id                           int auto_increment comment '主键'        primary key,create_date_time             timestamp                                null comment '数据创建时间',session_id                   varchar(48)                   default '' not null comment '会话系统sessionId',sid                          varchar(48) collate utf8_bin  default '' not null comment '访客id',create_time                  datetime                                 null comment '会话创建时间',seo_source                   varchar(255) collate utf8_bin default '' null comment '搜索来源',seo_keywords                 varchar(512) collate utf8_bin default '' null comment '关键字',ip                           varchar(48) collate utf8_bin  default '' null comment 'IP地址',area                         varchar(255) collate utf8_bin default '' null comment '地域',country                      varchar(16) collate utf8_bin  default '' null comment '所在国家',province                     varchar(16) collate utf8_bin  default '' null comment '省',city                         varchar(255) collate utf8_bin default '' null comment '城市',origin_channel               varchar(32) collate utf8_bin  default '' null comment '来源渠道(广告)',user                         varchar(255) collate utf8_bin default '' null comment '所属坐席',manual_time                  datetime                                 null comment '人工开始时间',begin_time                   datetime                                 null comment '坐席领取时间 ',end_time                     datetime                                 null comment '会话结束时间',last_customer_msg_time_stamp datetime                                 null comment '客户最后一条消息的时间',last_agent_msg_time_stamp    datetime                                 null comment '坐席最后一下回复的时间',reply_msg_count              int(12)                       default 0  null comment '客服回复消息数',msg_count                    int(12)                       default 0  null comment '客户发送消息数',browser_name                 varchar(255) collate utf8_bin default '' null comment '浏览器名称',os_info                      varchar(255) collate utf8_bin default '' null comment '系统名称'
);

web_chat_text_ems表结构:

create table web_chat_text_ems_2019_07
(id                   int                   not null comment '主键'       primary key,referrer             text collate utf8_bin null comment '上级来源页面',from_url             text collate utf8_bin null comment '会话来源页面',landing_page_url     text collate utf8_bin null comment '访客着陆页面',url_title            text collate utf8_bin null comment '咨询页面title',platform_description text collate utf8_bin null comment '客户平台信息',other_params         text collate utf8_bin null comment '扩展字段中数据',history              text collate utf8_bin null comment '历史访问记录'
);

3. 建模分析

3.1 提取指标维度

根据主题的需求,我们可以看出,包含的指标有一些是可以提取合并的:

  1. 地区独立访客热力图、总访问客户量、时间段访问客户量趋势、来源渠道访问量占比、搜索来源访问量占比、活跃页面排行榜的指标都可以合并为一个:访问客户量。
  2. 合并后的访问客户量指标,维度不同,而且数据来源也不同。
  3. 访客咨询率趋势、客户访问量和访客咨询率双轴趋势,都包含了访客咨询率指标。
  4. 访客咨询率=发起咨询的人数/访问客户量,分母访问客户量,可以复用前面的指标。因此只需要计算出分子:咨询客户量。

由此我们可以推断出,指标有两个:访问客户量和咨询客户量。

3.1.1 访问客户量

虽然访问客户量的时间维度只有年、季度、月,但是展示粒度要具体到天,所以统计时也要包含日维度。同时要求能够下钻到小时数据,所以维度中也要包含小时。

来源渠道访客量占比,虽然最终要的是占比的比值,但是这个比值是可以通过具体的访客量计算出来,所以我们只需要提供不同来源渠道的访客量数据,柱状图前端就能够自动的计算比值。因此这里的指标也归类于访问客户量,维度为来源渠道。

活跃页面排行榜,字面看是和页面相关的指标,实际统计的却是每个页面的访问客户量,然后再进行排序后得出的排行榜。所以这里的指标也归类于访问客户量,统计的维度是具体的页面。但是要注意这里的数据来源有变化。

维度包括:年、季度、月、天、小时(天区间内小时段)、地区、来源渠道、搜索来源、会话来源页面、总访问量。

3.1.2 咨询客户量

访客咨询率趋势统计中,访客咨询率=发起咨询的人数/访问客户量,分母访问客户量我们可以复制上面的指标数据,而分子咨询客户量则是我们要统计的新指标。

维度包括:年、季度、月、日、地区、来源渠道。

3.2 分层设计

3.2.1 访问客户量

抽取咨询原始数据到ODS层以后,如何分析出对应维度的数据呢?

我们可以采取结果导向的方式来进行倒推:

  1. 最终的数据维度:年、季度、月、日、小时、天区间内小时、地区、来源渠道、搜索来源、会话来源页面、总访问量;
  2. 首先要有DWD层对ODS原始数据进行清洗和转换,作为我们的明细数据;
  3. 维度我们可以分为两类:时间维度(年、季度、月、日、小时)和产品属性维度(地区、来源渠道、搜索来源、会话来源页面、总访问量);
  4. 我们可以将产品属性维度和最小的时间粒度(小时)来统计,作为共享表,放置在DWM层;
  5. 在DWM层小时数据的基础上,进行上卷sum统计(年、季度、月、日、小时),即可得到DWS层的数据集市;
  6. 注意:最终的数据要求在统计之前,要先根据客户进行去重,这也对我们的中间层进行了限制,不能简单的先按天去重count,然后再按月和年sum,因为不同天的客户可能存在重复,直接sum会导致结果不正确;
  7. 所以DWM层不能进行count,那么如果将DWD客户去重后的数据,直接保存为中间表呢?也会存在问题,因为如果DWM层把全表的用户去重后,在DWS层数据会存在丢失减少的情况,比如小时数据和天数据。
  8. DWS层直接根据DWD的数据进行统计,得出数据集市;
  9. 将宽表数据导出到mysql,由FineBI灵活选择APP数据字段进行展示。
  10. ODS —> DWD —> DWS。

目的: 要计算此主题, 需要如何构建数仓分层, 每一层需要有那些表, 表中有那些字段

  • ODS层: 源数据层

    • 作用:对接数据源, 将数据源中数据导入到ODS层, 和数据源保持相同粒度(数据源中有那些内容, 导入到ODS层也需要有那些内容)
    • 建模操作: 此层一般用于放置事实表和少量的维度表
    1) 在ODS层, 可以放置两张表(在业务端有二张跟此主题相关的事实表)web_chat_ems  和   web_chat_text_ems
    2) ODS层的两个表中字段 和  业务库中对应表的字段保持一致(业务库中表有几个字段, 此ODS层表中也应该有几个字段)注意:在后期执行操作的时候, 先进行全量分析过程, 然后后期都是增量分析,此时需要从ODS层拿到增量数据, 如何区分增量数据呢?核心点: 通过时间所以: 在ODS层建表的时候, 比业务库的表多一个字段,此字段主要作用用于标识抽取时间: start_time
    
  • DW层: 数据仓库层

    • DWD层: 明细层

      • 作用: 数据的清洗转换处理 和 进行少量的维度退化手段
      • 思考: 需要清洗什么内容 , 需要转换什么内容
      清洗什么内容?  没有清洗的工作 , 因为数据来源于mysql, 数据结构是完整, 同时所有数据都是需要的, 所以也不需要处理转换什么内容?1. create_time : (需求必须要转换)原始数据:  2019-07-02 00:00:00 发现: 一个字段里面糅杂了太多字段数据, 需要对其进行转换转换为:yearinfo  quarterInfo  monthinfo  dayinfo  hourinfo2. 将create_time转换为时间戳的操作(为了讲解时间函数)
      • 建模操作字段:
        ,create_time,
      hourinfo,yearinfo, quarterInfo,  monthinfo, dayinfo  注意: 以上字段, 是需要进行清洗和转换后, 保留的字段此时DWD层表:  将上述的字段 和 ODS层中事实表所有的字段汇总在一起, 构建成DWD层表实际在生产中,具体操作:  1) 第一种, 如果事实表中字段比较多, 一般做法 可以只将需要的字段抽取出来即可2) 第二种, 如果表中字段比较少, 一般做法, 全部都获取出来最终形成的表字段: sid,session_id,ip ,create_time,area,origin_channel,seo_source,referrer,from_url,landing_page_url,url_title,platform_description,other_params,history,msg_count
      hourinfo,yearinfo, quarterInfo,  monthinfo, dayinfo
      
    • DWM层: 中间层

      • 作用: 提前聚合操作(周期快照事实表) 和 维度退化操作
      1) 维度退化操作:  此功能在此主题中不存在, 因为没有维度表
      2) 做提前聚合操作: 比如说: 要分别按照 年 月  日 小时进行统计总访问量, 此时可以先按照小时统计总访问量 , 后的日 月 年可以在小时的基础上进行累加统计即可, 这样效率比较高思考, 访问咨询主题中, 是否可以进行提前聚合呢?  不能 在此看板中, 计算指标的 先 去重 在统计个数小案例: 2020-10-10 15  s01  2020-10-10 15  s022020-10-10 16  s012020-10-10 16  s032020-10-11 10  s022020-10-11 11  s04统计, 每个小时有几个用户数据呢?2020-10-10 15  22020-10-10 16  22020-10-11 10  12020-10-11 11  1统计, 每天有几个用户呢? 正确结果:2020-10-10  32020-10-11  2但是, 如果使用每个小时的统计结果, 来计算:2020-10-10  42020-10-11  2此时, 会发现有问题了....
      
      • 此时发现, 在此层, 既不能做维度退化, 也不能进行提前聚合, 所以 不需要DWM层
    • DWS层: 业务层

      • 作用: 针对指标, 进行细化维度统计操作
      指标: 访问量
      维度: 固有维度:  时间维度: 年 季度 月  天 小时产品属性维度:总访问量地区维度来源渠道维度搜索来源维度受访页面维度开发需求: 共计有 25个开发需求1) 统计每年 的总访问量2) 统计 每年 每季度的总访问量3) 统计 每年 每季度 每月的总访问量.....1) 统计每年 各个地区的总访问量2) 统计每年每季度 各个地区总访问量....1) 统计每年各个来源渠道的总访问量数据2) 统计每年每季度各个来源渠道的总访问量数据........在DWS层, 需要将每一个需求的结果统计出来, 然后存储在DWS层  , 针对每一个指标, 构建一个结果表, 存储其所有的结果DWS层表:组成部分:指标统计结果字段 + 维度字段  + 业务查询字段(time_type,group_type,time_str)最终组合下DWS层字段:sid_total,sessionid_total,ip_total,area,origin_channel,seo_sourcefrom_url, hourinfo,time_type,group_type,time_stryearinfo, quarterinfo,monthinfo,dayinfo,-------------------------------------
      指标:  咨询量
      维度:固有维度:  时间维度: 年 季度 月 天 小时产品属性维度:总咨询量地区维度来源渠道维度
      DWS层表:组成部分:指标统计结果字段 + 维度字段  + 业务查询字段(time_type,group_type,time_str)最终组合下DWS层字段:sid_total,sessionid_total,ip_total,area,origin_channelhourinfo,time_type,group_type,time_stryearinfo, quarterinfo,monthinfo,dayinfo,
  • APP层: 数据应用层

    • 作用: 对DWS层结果进行再次分析, 将统计结果存储在APP层
    思考: 是否还需要对DWS层数据进行统计?  ---> 是否在DWS层以及将需要的结果统计出来了?此时发现, 需要要求安装各个维度统计结果此时在DWS层以及统计完成了, 此时不需要在继续统计了, 所以不需要app层如果说, 需要计算比率 , 咨询率  此时可能需要app层
    
  • DIM层: 维表层

    • 此层不需要(因为没有维度表)

3.2.2 咨询客户量

  1. 最终的数据维度:年、季度、月、日、地区、来源渠道;
  2. 统计的数据和访问客户量指标相似,唯一的不同点是,多了一个条件:和客服有聊天信息;
  3. 因为咨询客户量的数据来源和访问客户量相同,所以ODS层可以复用;
  4. DWD层对ODS原始数据进行清洗和转换,可以复用;
  5. DWM层先去重,再在DWS中sum的结果是不正确的;所以跳过DWM层;
  6. DWS层直接在DWD层的基础上,加上聊天信息的条件后,按照维度进行统计。

4. 建模操作

4.1 数据存储格式

4.1.1 列式存储、行式存储

  • 行存储的特点: 查询满足条件的一整行(所有列)数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
  • 列存储的特点: 因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

4.1.2 TEXTFILE

默认格式,行式存储。可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。并且反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,性能较差。

4.1.3 ORCFILE

使用ORC文件格式可以提高hive读、写和处理数据的能力。ORCFile是RCFile的升级版。

在ORC格式的hive表中,数据按行分块,每块按列存储。结合了行存储和列存储的优点。记录首先会被横向的切分为多个stripes,然后在每一个stripe内数据以列为单位进行存储,所有列的内容都保存在同一个文件中。

每个stripe的默认大小为256MB,相对于RCFile每个4MB的stripe而言,更大的stripe使ORC可以支持索引,数据读取更加高效。

4.2 “存储格式&压缩格式”结合方式的选择

4.2.1 zlib压缩

优点:压缩率比较高;hadoop本身支持,在应用中处理gzip格式的文件就和直接处理文本一样。
缺点:压缩性能一般。

4.2.2 snappy压缩

优点:高速压缩速度和合理的压缩率。
缺点:压缩率比zlib要低;hadoop本身不支持,需要安装(CDH版本已自动支持,可忽略)。

因为ORCFILE的压缩快、存取快,而且拥有特有的查询优化机制,所以系统采用ORCFILE存储格式(RCFILE升级版),压缩算法采用orc支持的ZLIB和SNAPPY。

在ODS数据源层,因为数据量较大,可以采用orcfile+ZLIB的方式,以节省磁盘空间;

而在计算的过程中(DWD、DWM、DWS、APP),为了不影响执行的速度,可以浪费一点磁盘空间,采用orcfile+SNAPPY的方式,提升hive的执行速度。

存储空间足够的情况下,推荐采用SNAPPY压缩。

在项目中:

  • ODS层: ZLIB+ORC

  • 其他层次: SNAPPY + ORC

说明: 如果存储空间比较宽裕的, 建议在hive中建表时都可以采用snappy压缩方案

4.3 全量和增量

开发步骤共包含两大过程:全量过程和增量过程。

4.3.1 全量过程

全量过程是在首次建库时,需要对OLTP应用(Mysql)中的全量数据进行采集、清洗和统计计算。历史数据量可能会非常大,远远超出了增量过程。在执行时需要进行针对性的优化配置并采用分批执行。

4.3.2 增量过程

增量过程是在全量过程之后进行的,大多采用的是T+1模式。

全量执行完毕后,对OLTP每天的新增数据和更新数据要进行同步,如果还是对全量数据进行分析,效率会非常低下。增量数据只有一天的量,采集、清洗和统计的效率相对于全量过程会有很大提升。

什么是T+1?

这种说法来源于股票交易:

T+0,是国际上普遍使用的一种证劵度(或期货)交易制度。凡在证劵(或期货)成交日当天办理好证劵(或期货)和价款清算交割手续的交易制度,就称为T+0交易。通俗说,就是当天买入的证道劵(或期货)在当天就可以卖出。

T+1是一种股票交易制度,即当日买进的股票,要到下一个交易日才能卖出。“T”指交易登记日,“T+1”指登记日的次日。

4.4 Hive的分区

我们知道传统的OLTP数据库(Mysql)一般都具有索引和表分区的功能,通过表分区能够在特定的区域检索数据,减少扫描成本,在一定程度上提高查询效率,我们还可以通过建立索引进一步提升查询效率。在Hive数仓中也有索引和分区的概念。

为了对表进行合理的管理以及提高查询效率,Hive可以将表组织成“分区”。

分区是表的部分列的集合,可以为频繁使用的数据建立分区,这样查找分区中的数据时就不需要扫描全表,这对于提高查找效率很有帮助。

分区是一种根据“分区列”(partition column)的值对表进行粗略划分的机制。Hive中每个分区对应着表很多的子目录,将所有的数据按照分区列放入到不同的子目录中去。

4.4.1 为什么要分区

庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。

数据会依照单个或多个列进行分区,通常按照时间、地域或者是商业维度进行分区。

比如电影表,分区的依据可以是电影的种类和评级,另外,按照拍摄时间划分可能会得到均匀的结果。

为了达到性能表现的一致性,对不同列的划分应该让数据尽可能均匀分布。最好的情况下,分区的划分条件总是能够对应where语句的部分查询条件,这样才能充分利用分区带来的性能优势。

Hive的分区使用HDFS的子目录功能实现。每一个子目录包含了分区对应的列名和每一列的值。但是由于HDFS并不支持大量的子目录,这也给分区的使用带来了限制。我们有必要对表中的分区数量进行预估,从而避免因为分区数量过大带来一系列问题。

Hive查询通常使用分区的列作为查询条件。这样的做法可以指定MapReduce任务在HDFS中指定的子目录下完成扫描的工作。HDFS的文件目录结构可以像索引一样高效利用。

Hive(Inceptor)分区包括静态分区动态分区。根据插入时是否需要手动指定分区可以分为:

  • 静态分区:导入数据时需要手动指定分区;
  • 动态分区:导入数据时,系统可以动态判断目标分区;

4.4.2 静态分区

创建静态分区

  • 直接在 PARTITIONED BY 后面跟上分区键、类型即可。(分区键不能和任何列重名)

    CREATE [EXTERNAL] TABLE <table_name>(<col_name> <data_type> [, <col_name> <data_type> ...])-- 指定分区键和数据类型PARTITIONED BY  (<partition_key> <data_type>, ...) [ROW FORMAT <row_format>] [STORED AS TEXTFILE|ORC|CSVFILE][LOCATION '<file_path>']
    [TBLPROPERTIES ('<property_name>'='<property_value>', ...)];
    

    栗子:

    --分区字段主要是时间,按年分区
    CREATE TABLE device_open (
    deviceid varchar(50),
    ...
    )
    PARTITIONED BY (year varchar(50))
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
    

写入数据

  • 语法:

    -- 覆盖写入
    INSERT OVERWRITE TABLE <table_name> PARTITION (<partition_key>=<partition_value>[, <partition_key>=<partition_value>, ...]) SELECT <select_statement>;-- 追加写入
    INSERT INTO TABLE <table_name> PARTITION (<partition_key>=<partition_value>[, <partition_key>=<partition_value>, ...])
    SELECT <select_statement>;
    

    栗子:

    insert overwrite table device_open partition(year=’2020’)
    select...,original_device_open.month as month,original_device_open.day as day,original_device_open.hour as hour
    FROM original_device_open
    

4.4.3 动态分区

创建动态分区

  • 创建方式与静态分区表完全一样

    --分区字段主要是时间,分为年,月,日,时
    CREATE TABLE device_open (
    deviceid varchar(50),
    ...
    )
    PARTITIONED BY (year varchar(50), month varchar(50), day varchar(50), hour varchar(50))
    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
    
  • 写入(动态分区只需要给出分区键名称)
    -- 开启动态分区支持,并开启非严格模式
    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;insert overwrite table device_open partition(year,month,day,hour)
    select...,original_device_open.year as year,original_device_open.month as month,original_device_open.day as day,original_device_open.hour as hour
    FROM original_device_open
    
    • set hive.exec.dynamic.partition=true; 是开启动态分区
    • set hive.exec.dynamic.partition.mode=nonstrict; 这个属性默认值是strict,就是要求分区字段必须有一个是静态的分区值。全部动态分区插入,需要设置为nonstrict非严格模式。
    • partition(year,month,day,hour) 就是要动态插入的分区。对于大批量数据的插入分区,动态分区相当方便。

4.4.4 静态分区和动态分区混用

一张表可同时被静态和动态分区键分区,只是动态分区键需要放在静态分区键的后面(因为HDFS上的动态分区目录下不能包含静态分区的子目录)。

静态分区键要用 <spk>=<value> 指定分区值;动态分区只需要给出分区键名称 <dpk>

spk 即静态分区static partition key, dpk 即动态分区dynamic partition key。

比如:

insert overwrite table device_open partition(year='2017',month='05',day,hour)
select...,original_device_open.day as day,original_device_open.hour as hour
FROM original_device_open
where original_device_open.year='2017' and original_device_open.month='05'

partition(year=‘2017’, month=‘05’, day, hour),year和month是静态分区字段,day和hour是动态分区字段,这里指将2017年5月份的数据插入分区表,对应底层的物理操作就是将2017年5月份的数据load到hdfs上对应2017年5月份下的所有day和hour目录中去。

注意混用的情况下,静态分区的上层必须也是静态分区,如果partition(year, month, day=’05’, hour=’08’),则会报错:FAILED: SemanticException [Error 10094]: Line 1:50 Dynamic partition cannot be the parent of a static partition ‘‘day’’。

4.4.5 有序动态分区

注意,如果个人电脑性能不好,出现因为动态分区而导致的内存溢出问题,可以设置hive.optimize.sort.dynamic.partition进行避免:

设置为true后,当启用动态分区时,reducer仅随时保持一个记录写入程序,从而降低对 reducer产生的内存压力。但同时也会使查询性能变慢。

动态分区其他相关属性设置:

分区表的作用: 提升查询的性能,为什么说分区表可以提升查询性能呢?

原因:分区表可以将数据按照分区字段将其划分到多个文件夹中, 在查询的时候, 根据分区字段查询, 此时hive回到指定分区目录下查询数据, 不需要在查询其他目录, 从而可以减少查询数据的扫描量, 从而提升效率所以说 在hive中构建表的时候, 一般都是构建分区表

思考: 构建分区表, 如何向分区表添加数据

方案一: 静态分区(人为指定分区的值)格式:1) load data [local] inpath '路径' into|overwrite table 表名 partition(分区字段1=值1, 分区字段2=值2,...)2) insert into|overwrite table 表名 partition(分区字段1=值1,分区字段2=值2....) +select ....方案二: 动态分区(一次性向表中添加多个分区)格式:insert into|overwrite table 表名 partition(分区字段1,分区字段2....) +select ....注意:  如果使用动态分区, 必须满足以下条件1) 必须配置以下参数:set hive.exec.dynamic.partition=true; 开启动态分区支持set hive.exec.dynamic.partition.mode=nonstrict; 开启非严格模式2) select查询语句结果最后面必须是分区字段,而且要保证顺序方案三: 动静混合格式: insert into|overwrite table 表名 partition(分区字段1=值1,分区字段2,分区字段3....) +select ....注意:  如果使用动静混合分区, 必须满足以下条件1) 必须配置以下参数:set hive.exec.dynamic.partition=true; 开启动态分区支持set hive.exec.dynamic.partition.mode=nonstrict; 开启非严格模式2) select查询语句结果最后面必须是动态分区字段,而且要保证顺序

优化动态分区配置:

  • hive.optimize.sort.dynamic.partition
主要作用:当电脑内存资源不足时候, 可以开启此参数, 一旦开启, 整个hive翻译MR只会保持一个输出reduce, 从而降低资源的占用情况, 保证正常执行弊端: 执行效率会降低

4.3 建模操作

4.3.1 指标和维度

指标:访问客户量是单位时间内访问网站的去重后客户数量,以天为单位显示访问客户。

维度:

  • 时间维度:年、季度、月、天、小时
  • 业务属性维度:地区、来源渠道、搜索来源、会话来源页面、总访问量。

4.3.2 事实表和维度表

事实表的数据就是指标数据,访问客户量指标的事实表就是我们的客户访问表。而维度数据都包含在事实表中,没有需要额外关联的维度表。

4.3.3 分层

数据库命名统一加上前缀itcast,在实际场景中,将此前缀替换为系统的简称即可。比如:edu_ods、edu_dwd、edu_dws等。

  • ODS层是原始数据,一般不允许修改,所以使用外部表保证数据的安全性,避免误删除;
  • DW和APP层是统计数据,为了使覆盖插入等操作更方便,满足业务需求的同时,提高开发和测试效率,推荐使用内部表

4.3.3.1 ODS层

从咨询系统OLTP数据库(Mysql)的web_chat_ems_20XX_XX等月表中抽取的原始数据;

离线数仓大多数的场景都是T+1,为了便于后续的DW层清洗数据时,快速获取昨天的数据,ODS模型要在原始mysql表的基础之上增加starts_time抽取日期字段,并且可以使用starts_time字段分区以提升查询的性能。

  • 建库:

    -- 构建ODS的库
    CREATE DATABASE IF NOT EXISTS `itcast_ods`;
    
  • 建表:web_chat_ems

    • 建表时,要注意字段名不要采用关键字,比如原始mysql表中有一个user字段,我们需要将它修改为user_match。
    • 注意,设置ORC压缩格式前一定要先设置hive.exec.orc.compression.strategy,否则压缩不生效:
      --写入时压缩生效
      set hive.exec.orc.compression.strategy=COMPRESSION;
      
    CREATE EXTERNAL TABLE IF NOT EXISTS itcast_ods.web_chat_ems (id INT comment '主键',create_date_time STRING comment '数据创建时间',session_id STRING comment '七陌sessionId',sid STRING comment '访客id',create_time STRING comment '会话创建时间',seo_source STRING comment '搜索来源',seo_keywords STRING comment '关键字',ip STRING comment 'IP地址',area STRING comment '地域',country STRING comment '所在国家',province STRING comment '省',city STRING comment '城市',origin_channel STRING comment '投放渠道',user_match STRING comment '所属坐席',manual_time STRING comment '人工开始时间',begin_time STRING comment '坐席领取时间 ',end_time STRING comment '会话结束时间',last_customer_msg_time_stamp STRING comment '客户最后一条消息的时间',last_agent_msg_time_stamp STRING comment '坐席最后一下回复的时间',reply_msg_count INT comment '客服回复消息数',msg_count INT comment '客户发送消息数',browser_name STRING comment '浏览器名称',os_info STRING comment '系统名称')
    comment '访问会话信息表'
    PARTITIONED BY(starts_time STRING)
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '\t'
    stored as orc
    location '/user/hive/warehouse/itcast_ods.db/web_chat_ems_ods'
    TBLPROPERTIES ('orc.compress'='ZLIB');
    
  • 建表:web_chat_text_ems

    CREATE EXTERNAL TABLE IF NOT EXISTS itcast_ods.web_chat_text_ems (id INT COMMENT '主键来自MySQL',referrer STRING comment '上级来源页面',from_url STRING comment '会话来源页面',landing_page_url STRING comment '访客着陆页面',url_title STRING comment '咨询页面title',platform_description STRING comment '客户平台信息',other_params STRING comment '扩展字段中数据',history STRING comment '历史访问记录'
    ) comment 'EMS-PV测试表'
    PARTITIONED BY(start_time STRING)
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '\t'
    stored as orc
    location '/user/hive/warehouse/itcast_ods.db/web_chat_text_ems_ods'
    TBLPROPERTIES ('orc.compress'='ZLIB');
    

4.3.3.2 DWD层

维度:

  • 时间维度:年、季度、月、天、小时
  • 业务属性维度:地区、来源渠道、搜索来源、会话来源页面、总访问量。

建库:

-- 构建DWD的库
CREATE DATABASE IF NOT EXISTS `itcast_dwd`;

将ODS层数据,进行清洗转换,并且将web_chat_ems主表和web_chat_text_ems附表的内容根据id合并在一起。

数据粒度保持不变。

数据清洗:空数据、不满足业务需求的数据处理。

数据转换:数据格式和数据形式的转换,比如时间类型可以转换为同样的展现形式“yyyy-MM-dd HH:mm:ss”或者时间戳类型,金钱类型的数据可以统一转换为以元为单位或以分为单位的数值。

建表:

create table if not exists itcast_dwd.visit_consult_dwd(session_id STRING comment '七陌sessionId',sid STRING comment '访客id',create_time bigint comment '会话创建时间',seo_source STRING comment '搜索来源',ip STRING comment 'IP地址',area STRING comment '地域',msg_count int comment '客户发送消息数',origin_channel STRING COMMENT '来源渠道',referrer STRING comment '上级来源页面',from_url STRING comment '会话来源页面',landing_page_url STRING comment '访客着陆页面',url_title STRING comment '咨询页面title',platform_description STRING comment '客户平台信息',other_params STRING comment '扩展字段中数据',history STRING comment '历史访问记录',hourinfo string comment '小时',quarterinfo string comment '季度'
)
comment '访问咨询DWD表'
partitioned by(yearinfo String, monthinfo String, dayinfo string)
row format delimited fields terminated by '\t'
stored as orc
location '/user/hive/warehouse/itcast_dwd.db/visit_consult_dwd'
tblproperties ('orc.compress'='SNAPPY');

4.3.3.3 DWS层表

在DWD层的基础上,按照业务的要求进行统计分析;时间和业务属性三个维度分类,可以在模型中增加对应的属性标识:

  • 时间维度:1.年、2.季度、3.月、4.天、5.小时
  • 业务属性维度:1.地区、2.来源渠道、3.搜索来源、4.会话来源页面、5.总访问量

建库:

-- 构建DWS的库
CREATE DATABASE IF NOT EXISTS `itcast_dws`;

建表:

CREATE TABLE IF NOT EXISTS itcast_dws.visit_dws (sid_total INT COMMENT '根据sid去重求count',sessionid_total INT COMMENT '根据sessionid去重求count',ip_total INT COMMENT '根据IP去重求count',area STRING COMMENT '区域信息',seo_source STRING COMMENT '搜索来源',origin_channel STRING COMMENT '来源渠道',hourinfo STRING COMMENT '创建时间,统计至小时',quarterinfo STRING COMMENT '季度',time_str STRING COMMENT '时间明细',from_url STRING comment '会话来源页面',groupType STRING COMMENT '产品属性类型:1.地区;2.搜索来源;3.来源渠道;4.会话来源页面;5.总访问量',time_type STRING COMMENT '时间聚合类型:1、按小时聚合;2、按天聚合;3、按月聚合;4、按季度聚合;5、按年聚合;')
comment 'EMS访客日志dws表'
PARTITIONED BY(yearinfo STRING,monthinfo STRING,dayinfo STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
stored as orc
location '/user/hive/warehouse/itcast_dws.db/visit_dws'
TBLPROPERTIES ('orc.compress'='SNAPPY');CREATE TABLE IF NOT EXISTS itcast_dws.consult_dws
(sid_total INT COMMENT '根据sid去重求count',sessionid_total INT COMMENT '根据sessionid去重求count',ip_total INT COMMENT '根据IP去重求count',area STRING COMMENT '区域信息',origin_channel STRING COMMENT '来源渠道',hourinfo STRING COMMENT '创建时间,统计至小时',quarterinfo STRING COMMENT '季度',time_str STRING COMMENT '时间明细',groupType STRING COMMENT '产品属性类型:1.地区;2.来源渠道',time_type STRING COMMENT '时间聚合类型:1、按小时聚合;2、按天聚合;3、按月聚合;4、按季度聚合;5、按年聚合;'
)
COMMENT '咨询量DWS宽表'
PARTITIONED BY (yearinfo string, monthinfo STRING, dayinfo string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS ORC
LOCATION '/user/hive/warehouse/itcast_dws.db/consult_dws'
TBLPROPERTIES ('orc.compress'='SNAPPY');

4.3.3.4 APP层表

如果用户需要具体的报表展示,可以针对不同的报表页面设计APP层结构,然后导出至OLAP系统的mysql中。

如果系统使用FineBI,需要通过宽表来进行灵活的展现。则APP层不再进行细化。直接将DWS层导出至mysql即可。

5. 数据操作之前基础优化(Hive参数优化)

下面关于Hive的优化,皆是基于Hive2.x的版本,对于Hive1.x旧版本的优化机制不再复述(新版本已改善或变更)。

另外新版本中默认为开启状态的优化配置项,在工作中无需修改,也不再复述。

5.1 HDFS的副本数的调整

dfs.replication(HDFS)

文件副本数,通常设为3,不推荐修改。

如果测试环境只有二台虚拟机(2个datanode节点),此值要修改为2。

5.2 Yarn的相关配置

5.2.1 NodeManager配置

5.2.1.1 cpu配置

配置项:yarn.nodemanager.resource.cpu-vcores

表示该节点服务器上yarn可以使用的虚拟CPU个数,默认值是8,推荐将值配置与物理CPU线程数相同,如果节点CPU核心不足8个,要调小这个值,yarn不会智能的去检测物理核心数。

  • 默认值: 8

    表示: 每一个nodemanager对应服务器的cpu核心数为 8
    
  • 推荐配置: 和nodemanager对应服务器的cpu核心保持一致即可
    • 如何查询服务器的cpu的核心数呢?

      grep 'processor' /proc/cpuinfo | sort -u | wc -l
      

  • 如何配置
5.2.1.2 内存配置

配置项: yarn.nodemanager.resource.memory-mb | yarn.scheduler.maximum-allocation-mb | yarn.app.mapreduce.am.command-opts

说明:yarn.nodemanager.resource.memory-mb | yarn.scheduler.maximum-allocation-mb : 内存大小配置一致yarn.app.mapreduce.am.command-opts : 略小于 上面的配置 0.9 左右
  • 默认值: 8GB

  • 推荐配置: 当前服务器剩余内存 * 0.8

  • 如何查看电脑剩余内存呢?

    • shell命令查询: free -m

    • 通过CM查看:

  • 如何配置:

5.2.2 MR的基础配置

大数据-案例-离线数仓-在线教育:MySQL(业务数据)-ETL(Sqoop)->Hive数仓【ODS层-数据清洗->DW层(DWD-统计分析->DWS)】-导出(Sqoop)->MySQL->可视化相关推荐

  1. 在线教育投融数据(2015-2020年)

    一.数据介绍 数据名称:在线教育投融数据(2015-2020年) 数据年份:2015-2020年 样本数量:3182家在线教育公司 数据指标:时间.公司名称.公司名称链接.行业.轮次.金额.投资方.最 ...

  2. 大数据【企业级360°全方位用户画像】业务数据调研及ETL

    写在前面: 博主是一名大数据的初学者,昵称来源于<爱丽丝梦游仙境>中的Alice和自己的昵称.作为一名互联网小白,写博客一方面是为了记录自己的学习历程,一方面是希望能够帮助到很多和自己一样 ...

  3. 微服务架构案例(03):数据库选型简介,业务数据规划设计

    本文源码:GitHub·点这里 || GitEE·点这里 更新进度(共6节): 01:项目技术选型简介,架构图解说明 02:业务架构设计,系统分层管理 03:数据库选型,业务数据设计规划 一.数据库选 ...

  4. 第二章 数据采集模块之FlinkCDC实时采集Mysql业务数据(源码资料见文末)

    1.Mysql数据准备 (1)创建实时同步数据库 create database flink_gmall (2)将Mysql.sql文件导入到Mysql中 source /opt/data/Mysql ...

  5. 大数据-案例-离线数仓-电商:【MySQL(业务)-ETL(Kettle)】+【前端JS埋点->日志->Flume->HDFS->ETL(SparkRDD)】->Hive数仓->MySQL->可视化

    一.电商行业简介 1.电商行业分析 近年来,中国的电子商务快速发展,交易额连创新高,电子商务在各领域的应用不断拓展和深化.相关服务业蓬勃发展.支撑体系不断健全完善.创新的动力和能力 不断增强.电子商务 ...

  6. 大数据技术之电商推荐系统(4) | 初始化业务数据

    目录 一.数据加载准备 Products数据集 Ratings数据集 日志管理配置文件 二.数据初始化到MongoDB 启动MongoDB数据库(略) 数据加载程序主体实现 三.扩展写到Mysql里 ...

  7. 在线教育大数据营销平台实战(搭建篇)

    作者介绍:TigerHu,某在线教育企业大数据营销产品负责人,主导数据产品线和营销 CRM 产品线. 本文内容均从作者真实实践过程出发,结合在线教育业务背景和当时的客观条件,深入分析大数据营销平台实战 ...

  8. 黑马在线教育数仓实战1

    1. 教育项目的架构说明 项目的架构:      基于cloudera manager大数据统一管理平台, 在此平台之上构建大数据相关的软件(zookeeper,HDFS,YARN,HIVE,OOZI ...

  9. 在线教育行业十大盈利模式分析

    在商言商,在线教育作为新兴的商业机会,利益是支撑一个行业持续与良好发展下去的核心.如果在线教育得不到有利的套现,那么又将是一个空中楼阁,虚幻的泡沫.众所周知,课程收费是众多教育机构的核心盈利模式,那么 ...

最新文章

  1. 4、EIGRP配置实验之手动汇总
  2. JS模块化工具requirejs教程02
  3. 文本分类入门(四)训练Part 1
  4. [C++] 匿名管道的理解与实现
  5. 计算机应用基础期中上机考试,期中考试计算机应用基础试卷
  6. windows 安装 zabbix agent 客户端
  7. Mouse Jiggler – 自动移动光标,防止电脑启动屏保、进入休眠[Windows]
  8. 【hdu 6396】Swordsman
  9. xgboost算法原理_从XGB到SecureBoost:看联邦学习XGB的算法原理
  10. Android ueventd浅析
  11. linuxshell编程_使shell命令发包软件-当你在Linux shell调用外部程序,如
  12. win7鼠标指针主题包_轻松办公之全局鼠标手势软件
  13. A pretty carpet
  14. ios系统怎么编辑html,word转html ios 可编辑
  15. 字蛛(FontSpider,中文字体压缩器)网页自由引入中文字体
  16. 黑产系列02-黑产画像
  17. 【附源码】计算机毕业设计SSM商品推荐系统
  18. php中seq是什么意思,seq-answer
  19. 解决办法:Ubuntu 16.04 【缺少依赖】导致出现该错误——ERROR: the following packages/stacks could not have their
  20. 麦子:我奋斗了18年才和你坐在一起喝咖啡

热门文章

  1. 教你ios10怎么降级到ios9.3.2
  2. wemos D1 arduino项目实战1-Tlink平台创建一个产品
  3. 被称"硬盘杀手"的几个win7系统服务如何关闭(转)
  4. 错位排列问题(递推法)
  5. MVP模式分析及简单例子
  6. 笔记本电脑打开后不显示桌面_Windows 10 这些鲜为人知的骚操作,90%的人都不知道...
  7. 盘一盘 QuantLib 系列 7 - SOFR OIS/FR007 IRS
  8. 27岁学python编程_五一4天就背这些Python面试题了,Python面试题No12
  9. Colab实用教程(免费的深度学习GPU环境)
  10. 平面设计和3D建模学哪个好?前景、薪资、技能需求各方面对比