第一阶段:环境与数据准备

启动 Hadoop: start-all.sh(start-dfs.sh、start-yarn.sh

# 1. 创建简单目录 mkdir -p /data/didi

上传数据文件到文件夹【hadoop02】

第二阶段:构建 Hive 数仓 (ODS -> DW -> APP)

进入 Hive 客户端:hive

【hadoop3】启动 Hive Metastore: hive --service metastore

启动hive的远程模式

1)启动MetaStore服务:【hadoop3】hive --service metastore

2)启动HIveServer2服务:【hadoop3】hive --service hiveserver2

3)连接MetaStore服务【hadoop2】hive

如启动不成功,退出安全模式:hdfs dfsadmin -safemode leave

初始化数据库

create database if not exists ods_didi;
create database if not exists dw_didi;
create database if not exists app_didi;

ODS 层表结构创建

1️⃣ 用户订单表(ods_didi.t_user_order)

use ods_didi;

create external table if not exists t_user_order(
orderId string,
telephone string,
lng string,
lat string,
province string,
city string,
es_money double,
gender string,
profession string,
age_range string,
tip double,
subscribe int,
sub_time string,
is_agent int,
agent_telephone string,
order_time string
)
partitioned by (dt string)
row format delimited fields terminated by ',';

2️⃣ 取消订单表

create external table if not exists t_user_cancel_order(
orderId string,
cstm_telephone string,
lng string,
lat string,
province string,
city string,
es_distance double,
gender string,
profession string,
age_range string,
reason int,
cancel_time string
)
partitioned by (dt string)
row format delimited fields terminated by ',';

3️⃣ 支付表

create external table if not exists t_user_pay_order(
id string,
orderId string,
lng string,
lat string,
province string,
city string,
total_money double,
real_pay_money double,
passenger_additional_money double,
base_money double,
has_coupon int,
coupon_total double,
pay_way int,
mileage double,
pay_time string
)
partitioned by (dt string)
row format delimited fields terminated by ',';

4️⃣ 评价表

create external table if not exists t_user_evaluate(
id string,
orderId string,
passenger_telephone string,
passenger_province string,
passenger_city string,
eva_level int,
eva_time string
)
partitioned by (dt string)
row format delimited fields terminated by ',';

加载数据到 Hive

use ods_didi;
 

-- 加载订单数据
load data local inpath '/data/didi/order.txt' into table ods_didi.t_user_order partition (dt='2020-04-12'); 

-- 加载取消订单数据
load data local inpath '/data/didi/cancel_order.txt' into table ods_didi.t_user_cancel_order partition (dt='2020-04-12'); 

-- 加载支付数据
load data local inpath '/data/didi/pay.txt' into table ods_didi.t_user_pay_order partition (dt='2020-04-12'); 

-- 加载评价数据
load data local inpath '/data/didi/evaluate.txt' into table ods_didi.t_user_evaluate partition (dt='2020-04-12');

验证数据是否加载成功

DW 层:数据清洗与宽表构建

建表语句

create table if not exists dw_didi.t_user_order_wide(
    orderId string comment '订单id',
    telephone string comment '打车用户手机',
    lng string comment '用户发起打车的经度',
    lat string comment '用户发起打车的纬度',
    province string comment '所在省份',
    city string comment '所在城市',
    es_money double comment '预估打车费用',
    gender string comment '用户信息 - 性别',
    profession string comment '用户信息 - 行业',
    age_range string comment '年龄段(70后、80后、...)',
    tip double comment '小费',
    subscribe int comment '是否预约(0 - 非预约、1 - 预约)',
    subscribe_name string comment '是否预约名称',
    sub_time string comment '预约时间',
    is_agent int comment '是否代叫(0 - 本人、1 - 代叫)',
    is_agent_name string comment '是否代叫名称',
    agent_telephone string comment '预约人手机',
    order_date string comment '预约时间,yyyy-MM-dd',
    order_year string comment '年',
    order_month string comment '月',
    order_day string comment '日',
    order_hour string comment '小时',
    order_time_range string comment '时间段',
    order_time string comment '预约时间'
)
partitioned by (dt string comment '时间分区') 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' ; 

预处理SQL语句

select 
    orderId,
    telephone,
    lng,
    lat,
    province,
    city,
    es_money,
    gender,
    profession,
    age_range,
    tip,
    subscribe,
    case when subscribe = 0 then '非预约'
         when subscribe = 1 then'预约'
    end as subscribe_name,
     date_format(concat(sub_time,':00'), 'yyyy-MM-dd HH:mm:ss') as sub_time,
    is_agent,
    case when is_agent = 0 then '本人'
         when is_agent = 1 then '代叫'
    end as is_agent_name,
    agent_telephone,
   date_format(regexp_replace(order_time, '/', '-'), 'yyyy-MM-dd') as order_date, -- 2020-1-1 --->2020-01-01
    year(date_format(regexp_replace(order_time, '/', '-'), 'yyyy-MM-dd')) as order_year, --2020
    month(date_format(regexp_replace(order_time, '/', '-'), 'yyyy-MM-dd')) as order_month, --12
    day(date_format(regexp_replace(order_time, '/', '-'), 'yyyy-MM-dd')) as order_day, --23
    hour(date_format(concat(regexp_replace(regexp_replace(order_time, '/', '-'), '/', '-'),":00"), 'yyyy-MM-dd HH:mm:ss')) as order_hour,
    case when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 1 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 5 then '凌晨'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 5 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 8 then '早上'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 8 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 11 then '上午'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 11 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 13 then '中午'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 13 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 17 then '下午'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 17 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 19 then '晚上'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 19 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 20 then '半夜'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) > 20 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 24 then '深夜'
         when hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) >= 0 and hour(date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss')) <= 1 then '凌晨'
         else 'N/A'
     end as order_time_range,
    date_format(concat(regexp_replace(order_time, '/', '-'),':00'), 'yyyy-MM-dd HH:mm:ss') as order_time
from ods_didi.t_user_order where dt = '2020-04-12' and length(order_time) >= 8 ;

4)连接HIveServer2服务【hadoop2】beeline -u idbc:hive2://hadoop3:10000 -n root

更多推荐