离线数据处理 任务三:指标计算

目录

在mysql中建数据表

任务

        接着数据清洗后的数据继续练习

在mysql中建数据表

        1、创建shtd_result数据库

create database shtd_result;

        2、创建provinceeverymonth表

CREATE TABLE `provinceeverymonth`  (
  `provinceid` int(20) COMMENT '省份表主键',
  `provincename` varchar(20) COMMENT '省份名称',
  `regionid` int(20) COMMENT '地区表主键',
  `regionname` varchar(20) COMMENT '地区名称',
  `totalconsumption` double COMMENT '订单金额',
  `totalorder` int(20) COMMENT '订单总数',
  `year` int(20) COMMENT '订单产生的年',
  `month` int(20) COMMENT '订单产生的月'
);

        3、创建 provinceavgcmp表

CREATE TABLE `provinceavgcmp`  (
  `provinceid` int(20) COMMENT '省份表主键',
  `provincename` varchar(20) COMMENT '省份名称',
  `provinceavgconsumption` double COMMENT '该省平均订单金额',
  `allprovinceavgconsumption` double COMMENT '所有省平均订单金额',
  `comparison` varchar(20) COMMENT '比较结果'
);

        4、创建usercontinueorder表

CREATE TABLE `usercontinueorder`  (
  `userid` int(20) COMMENT '客户主键',
  `username` varchar(20) COMMENT '客户名称',
  `day` varchar(20) COMMENT '日',
  `totalconsumption` double COMMENT '订单总金额',
  `totalorder` int(20) COMMENT '订单总数'
);

 任务

使用Scala编写spark工程代码,并计算相关指标。

:在指标计算中,不考虑订单信息表中order_status字段的值将所有订单视为有效订单计算订单金额或订单总金额时只使用final_total_amount字段。需注意dwd所有的维表取最新的分区。

1、根据dwd层表统计每个省份、每个地区、每个月下单的数量和下单的总金额,存入MySQL数据库shtd_result的provinceeverymonth表中,然后在Linux的MySQL命令行中根据订单总数、订单总金额、省份表主键均为降序排序,查询出前5条 

        如果存入mysql中字符类型数据变成了问号 

useUnicode=yes&characterEncoding=utf8

        则更改配置数据库的部分,一般是url,我的是application.yml里的配置url里或者在指定存储路径后加上该配置。 

 def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("sum")
    val spark: SparkSession = SparkSession.builder().enableHiveSupport().config(conf).getOrCreate()
    //mysql对象
    val pro: Properties = new Properties()
    pro.put("user","root")
    pro.put("password","p@ssw0rd")
    pro.put("driver","com.mysql.jdbc.Driver")
    //mysql连接
    val mTable: Unit = spark.read.jdbc("jdbc:mysql://master:3306/shtd_result", "provinceeverymonth", pro)
      .createOrReplaceTempView("mysql_table")
    val df: DataFrame = spark.sql(
      """
        |select
        |cast(t1.id as int) provinceid,
        |cast(t1.name as string) provincename,
        |cast(t2.id as int) regionid,
        |cast(t2.region_name as string) regionname,
        |cast(SUM(t3.final_total_amount) as double) totalconsumption,
        |cast(COUNT(t4.order_id)as int) totalorder ,
        |cast(YEAR(t2.create_time) as int) year,
        |cast(MONTH(t2.create_time) as int) month
        |from dwd.dim_base_province t1
        | left join dwd.dim_base_region t2
        | on t1.region_id = t2.id and t2.etl_date = '20230403'
        | left join dwd.fact_order_info t3
        | on t1.id = t3.province_id and t3.etl_date = '20230401'
        | left join dwd.fact_order_detail t4
        | on t1.id = t4.sku_id and t4.etl_date = '20230401'
        |where t1.etl_date = '20230403'
        |group by
        |t1.id,t1.name,t2.id,t2.region_name,year,month
        |""".stripMargin)

    //写入mysql
    df.write.mode(SaveMode.Overwrite).jdbc("jdbc:mysql://master:3306/shtd_result?useUnicode=yes&characterEncoding=utf8","provinceeverymonth",pro)

    //查看写入的数据
    spark.sql("select * from mysql_table order by totalorder desc,totalconsumption desc,provinceid desc limit 5").show
    spark.close()
  }

2、请根据dwd层表计算出2020年4月每个省份的平均订单金额和所有省份平均订单金额相比较结果(“高/低/相同”),存入MySQL数据库shtd_result的provinceavgcmp表中,然后在Linux的MySQL命令行中根据省份表主键、该省平均订单金额均为降序排序,查询出前5条 

def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("sum")
    val spark: SparkSession = SparkSession.builder().enableHiveSupport().config(conf).getOrCreate()
    //mysql对象
    val pro: Properties = new Properties()
    pro.put("user","root")
    pro.put("password","p@ssw0rd")
    pro.put("driver","com.mysql.jdbc.Driver")
    //mysql连接
    val mTable: Unit = spark.read.jdbc("jdbc:mysql://master:3306/shtd_result", "provinceavgcmp", pro)
          .createOrReplaceTempView("mysql_table")

    val df: DataFrame = spark.sql(
      """
        |select
        |  cast(t1.id as int) provinceid,
        |  cast(t1.name as string) provincename,
        |  cast(t2.pavg as double) provinceavgconsumption,
        |  cast(t2.allpavg as double) allprovinceavgconsumption,
        |  CASE
        |    WHEN t2.pavg > t2.allpavg THEN '高'
        |    WHEN t2.pavg < t2.allpavg THEN '低'
        |    ELSE '相同'
        |  END comparison
        |from dwd.dim_base_province t1
        |join (
        |  select
        |    tmp.province_id id,
        |    AVG(tmp.final_total_amount) pavg,
        |    (
        |      select AVG(final_total_amount)
        |      from dwd.fact_order_info
        |      where YEAR(create_time) = 2020 and MONTH(create_time) = 4
        |    ) allpavg
        |  from dwd.fact_order_info tmp
        |  where YEAR(tmp.create_time) = 2020 and MONTH(tmp.create_time) = 4
        |  group by tmp.province_id
        |) t2
        |on t1.id = t2.id
        |""".stripMargin)
    

    //写入mysql
    df.write.mode(SaveMode.Overwrite).jdbc("jdbc:mysql://master:3306/shtd_result?useUnicode=yes&characterEncoding=utf8","provinceavgcmp",pro)

    //查看写入的数据
    spark.sql("select * from mysql_table order by provinceid desc,provinceavgconsumption desc limit 5").show()
    spark.close()
  }

3、根据dwd层表统计在两天内连续下单并且下单金额保持增长的用户,存入MySQL数据库shtd_result的usercontinueorder表中,然后在Linux的MySQL命令行中根据订单总数、订单总金额、客户主键均为降序排序,查询出前5条 

def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("sum")
    val spark: SparkSession = SparkSession.builder().enableHiveSupport().config(conf).getOrCreate()
    //mysql对象
    val pro: Properties = new Properties()
    pro.put("user","root")
    pro.put("password","p@ssw0rd")
    pro.put("driver","com.mysql.jdbc.Driver")
    //mysql连接
    val mTable: Unit = spark.read.jdbc("jdbc:mysql://master:3306/shtd_result", "usercontinueorder", pro)
          .createOrReplaceTempView("mysql_table")

    val df: DataFrame = spark.sql(
      """
        |select
        |T1.user_id userid,
        |T1.consignee username,
        |CONCAT(T1.day, '-', T2.day) day,
        |SUM(T1.final_total_amount + T2.final_total_amount) totalconsumption,
        |COUNT(T1.order_id) totalorder
        |from
        |(select
        |t1.user_id,
        |t1.consignee,
        |date_sub(t1.create_time, 1) day,
        |SUM(t1.final_total_amount) final_total_amount,
        |COUNT(t2.order_id) order_id
        |from dwd.fact_order_info t1
        |left join dwd.fact_order_detail t2
        |on t1.user_id = t2.id
        |group by t1.user_id,t1.consignee,date_sub(t1.create_time, 1)
        |) T1 left join
        |(select
        |t1.user_id,
        |t1.consignee,
        |date_sub(t1.create_time, 2) day,
        |SUM(t1.final_total_amount) final_total_amount,
        |COUNT(t2.order_id) order_id
        |from dwd.fact_order_info t1
        |left join dwd.fact_order_detail t2
        |on t1.user_id = t2.id
        |group by t1.user_id,t1.consignee,date_sub(t1.create_time, 2)
        |) T2
        |on T1.user_id = T2.user_id and T1.final_total_amount > T2.final_total_amount
        |group by T1.user_id, T1.consignee, CONCAT(T1.day, '-', T2.day)
        |""".stripMargin)
    df


    //写入mysql
    df.write.mode(SaveMode.Overwrite).jdbc("jdbc:mysql://master:3306/shtd_result?useUnicode=yes&characterEncoding=utf8","usercontinueorder",pro)

    //查看写入的数据
    spark.sql("select * from mysql_table order by totalorder desc,totalconsumption desc,userid desc limit 5").show()
    spark.close()
  }
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: Flink和Spark都是流行的分布式数据处理框架,它们都能够有效地处理大规模的数据,并且都支持在分布式环境下运行。但是,它们的一些设计和实现方面存在差异,因此它们在某些情况下的表现可能会不同。 以下是Flink相对于Spark的一些特点: 1. 低延迟:Flink支持基于事件时间(Event Time)的处理,这意味着它能够处理无序事件流并保证低延迟。Spark不支持事件时间,因此在处理无序事件时可能会有较高的延迟。 2. 高吞吐量:Flink支持基于处理时间(Processing Time)的处理,并且它的运行时引擎(Runtime)是基于异步、非阻塞的I/O模型实现的,这使得它能够实现非常高的吞吐量。Spark的运行时引擎则是基于阻塞式I/O模型实现的,因此在吞吐量方面可能会略逊于Flink。 3. 更好的状态管理:Flink支持分布式快照(Snapshotting)和容错性(Fault Tolerance),这使得它在状态管理方面更加出色。Spark在这方面的支持较为有限。 4. 更好的流式查询支持:Flink支持流式SQL查询和流式Table API,这使得它能够更方便地处理和查询流式数据。Spark在这方面的支持也较为有限。 总的来说,Flink和Spark都是强大的分布式数据处理框架,它们在某些方面的特点和表现可能会有所不同。在选择使用哪个框架时,应该根据具体的应用场景和需求来进行评估和选择。 ### 回答2: Flink是一个高性能的分布式流处理和批处理计算框架,而Spark是一个通用的大数据处理框架,可以进行批处理、流处理和机器学习等多种任务。因此,在离线数据处理方面,Spark和Flink都有其优势和特点。 首先,Flink在流处理方面具有优势。Flink的流处理引擎支持低延迟、高吞吐量的事件驱动计算。它提供了精确一次语义(exactly-once semantics)的处理保证,能够处理无限数据流并保持数据的顺序。因此,对于实时性要求较高的场景,Flink在离线数据处理方面表现得更好。 其次,Spark在批处理方面更强大。Spark的RDD(弹性分布式数据集)提供了高度可靠、高性能的批处理计算能力。它采用了内存计算技术,能够将数据存储在内存中进行快速操作,从而提高计算速度。此外,Spark还提供了丰富的生态系统,包括SQL、机器学习、图计算等功能,适用于各种离线数据处理任务。 虽然Flink在离线数据处理方面相对于Spark来说可能稍显逊色,但它在流处理方面的优势使得它在实时性要求较高或需要处理无限数据流的场景下更具竞争力。同时,Flink也在逐渐发展和完善其批处理能力,提供更好的离线数据处理效果。 总而言之,Flink的离线数据处理效果不一定比Spark差,取决于具体的场景和需求。对于实时性要求较高的场景,Flink在离线数据处理方面可能更合适,而对于批处理任务,Spark可能更具优势。 ### 回答3: Flink和Spark都是目前非常流行的大数据处理框架,它们在离线数据处理方面都有各自的优势和特点。 首先,Flink的数据处理模型是基于流式计算的,它可以处理无界流数据和有界流数据。相比之下,Spark的数据处理模型主要面向有界流数据,对无界流数据的处理能力较弱。所以在对实时和流式数据的处理上,Flink的效果更好。 其次,Flink在数据处理的低延迟方面表现出色。Flink具有极低的事件处理延迟,可以实现毫秒级的实时数据处理。而Spark在低延迟的处理上相对较弱,通常需要更多的计算资源来达到较低的延迟。 另外,Flink的状态管理和容错机制也十分强大,可以保证精确一次性处理语义。Flink可以将所有计算数据的中间结果和状态进行持久化存储,保证了在计算过程中发生故障或节点失效时的数据可靠性和一致性。而Spark的容错机制是基于RDD的,有时候因为依赖关系过于复杂而导致处理效果较差。 总的来说,Flink在流式数据和低延迟处理方面优势明显,更适合实时和流式数据场景。而Spark则更适合对有界流数据进行离线批处理,它有更好的生态系统支持和更丰富的算法库。所以不能单纯地说Flink的离线数据处理效果不如Spark,而是需要根据具体场景和需求来选择合适的框架。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

open_test01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值