问题导读
1.实际工作中,分析数据有哪些工作?
2.本文涉及了几张表?
3.分析了几张表?
4.本文分析数据 任务是什么?
关注最新经典文章,欢迎关注公众号
我们大数据开发与传统开发到底有什么区别?很多同学对于大数据开发,仍然抱有神秘感。如果我们要分析数据,我们需要做哪些工作。是不是我们只要用sql简单的统计下就可以了。
说的其实也对,因为本身的核心业务就是分析,但是为了分析我们需要做大量的工作,这也是我们在实际工作需要做的。
比如首先我们需要有待分析的数据,这里待分析的数据是mysql的数据。数据有了,我们要使用大数据,因为我们需要将数据转移到hdfs上,转移之后,我们在使用hive进行分析。这就是我们实际工作中,与我们理想课程的学习的区别。这里面不止有技术,而且涉及不断重复的工作。当你已经入职工作之后,或许你会看到其实用到的技术也就那样,剩下的就是不断重复,而我们大多数公司,其实也就是不断的重复而已。
在这里,我们提供了一个电子商务公司的商业用例,该公司希望分析他们的交易并从中获取一些有用的建议,这对他们的业务发展很有用。
以下是电子商务公司的数据库设计E-R图。
(对于上面未做过业务的学生,及公司想做这方面的业务,可以学习和借鉴,我们可以看到上面关系及有多少张表)
1.待分析数据
让我们从根据这个E-R图表创建表开始。
首先,我们将创建一个数据库来存储我们的表。 我们将数据库命名为ecom。
create database ecom;
use ecom;
复制代码
我们现在已经成功创建了数据库,并将其移动到该数据库中。 我们可以在下面的屏幕截图中看到相同的内容:
现在,我们将根据E-R图创建电子商务网站所需的所有表。
创建表user_accountcreate table user_account
(
ac_no int,
user_id varchar(30),
user_pswd varchar(30),
date datetime,
no_of_visit int,
no_of_trnsc int,
trnsc_amt int,
primary key(ac_no)
);
复制代码
插入数据insert into user_account values(125,'a123','pp284','2011-04-14',5,6,100);insert into user_account values(126,'a124','rr999','2012-06-13',2,3,1000);
insert into user_account values(127,'a125','ab888','2010-07-15',3,9,5000);
insert into user_account values(128,'a126','bb900','2016-05-15',1,8,7000);
insert into user_account values(129,'a127','rt007','2012-07-14',4,5,4000);
insert into user_account values(130,'a128','ss008','2013-03-15',6,2,8000); 复制代码
创建表user_session_detailscreate table user_session_details(
ac_no int,
session_no int,
ip_address varchar(30),
no_of_clicks int,
date datetime,
primary key(session_no),
foreign key(ac_no) references user_account(ac_no)
); 复制代码
插入数据
insert into user_session_details values(130,11,'10.23.130.162',5,'2016-05-14');
insert into user_session_details values(130,10,'11.26.135.167',5,'2014-09-15');
insert into user_session_details values(125,9,'11.58.123.151',3,'2012-10-13');
insert into user_session_details values(127,3,'11.33.111.188',2,'2015-01-14');
insert into user_session_details values(129,15,'11.37.101.142',7,'2014-10-17');
insert into user_session_details values(128,8,'11.67.100.123',6,'2012-09-12'); 复制代码
创建表shopping_cart_details
create table shopping_cart_details
(
ac_no int,
cart_num int,
active_status boolean,
expire_date datetime,
primary key(cart_num),
foreign key(ac_no) references user_account(ac_no)
); 复制代码
插入数据
insert into shopping_cart_details values(128,144,'0','2014-11-15');
insert into shopping_cart_details values(125,178,'0','2016-03-13');
insert into shopping_cart_details values(126,156,'1','2013-07-14');
insert into shopping_cart_details values(127,158,'1','2015-02-15');
insert into shopping_cart_details value(130,161,'1','2016-04-15');
insert into shopping_cart_details value(129,190,'1','2013-01-13'); 复制代码
创建表库存详细信息
create table inventory_item_details
(
inven_item_no int,
title int,
price int,
date datetime,
primary key(inven_item_no)
); 复制代码
插入数据
insert into inventory_item_details values(188,78,1500,'2013-10-15');
insert into inventory_item_details values(122,54,5000,'2014-09-14');
insert into inventory_item_details values(167,56,4500,'2015-11-11');
insert into inventory_item_details values(134,66,4000,'2014-01-16');
insert into inventory_item_details values(156,35,3000,'2015-12-07');
insert into inventory_item_details values(177,88,6000,'2013-02-17'); 复制代码
创建表地址
create table address
(
adrss_no int,
name varchar(30),
adrss_1 varchar(30),
adrss_2 varchar(30),
city varchar(30),
state varchar(30),
zip int,
primary key(adrss_no)
); 复制代码
插入数据
insert into address values(13,'Blossoms','KS layout','Marathalli','Bangalore','Karnataka',560037);
insert into address values(15,'Prestige','Ecity','HSR Layout','Bangalore','Karnataka',560048);
insert into address values(16,'Orchid','vimaan nagar','Whitefield','Pune','Maharashtra',460056);
insert into address values(24,'Alpino','KS layout','connaught place','Delhi','New Delhi',460008);
insert into address values(18,'Galaxy','BTM Layout','Cunningham road','Bangalore','Karnataka',560027);
insert into address values(11,'Pratiksha','TR layout','Andheri East','Mumbai','Maharashtra',760037); 复制代码
创建表credit_card_details
create table credit_card_details
(
ac_no int,
adrss_no int,
ccard_no int,
card_no varchar(30),
holder_name varchar(30),
expire_date datetime,
primary key(ccard_no),
foreign key(ac_no) references user_account(ac_no),
foreign key (adrss_no) references address(adrss_no)
); 复制代码
插入数据
insert into credit_card_details values(126,13,345,'AB24563789','Shalini','2019-05-12');
insert into credit_card_details values(125,15,679,'HD54654458','Sakshi','2020-06-11');
insert into credit_card_details values(127,24,145,'KK98735476','Kiran','2021-11-18');
insert into credit_card_details values(128,11,211,'AA54673825','Alex','2025-08-14');
insert into credit_card_details values(129,18,978,'CB64738463','Rose','2023-01-16');
insert into credit_card_details values(130,16,667,'BB37845678','Lisa','2021-10-10'); 复制代码
创建表payment_detailscreate table payment_details
(
ccard_no int,
payment_no int,
amt int,
state varchar(30),
date datetime,
primary key(payment_no),
foreign key(ccard_no) references credit_card_details(ccard_no)
); 复制代码
插入数据
insert into payment_details values(679,80,6600,'success','2014-11-16');
insert into payment_details values(345,67,8000,'success','2014-06-21');
insert into payment_details values(211,56,9000,'success','2015-02-25');
insert into payment_details values(145,78,1000,'failed','2015-05-22');
insert into payment_details values(667,12,5000,'success','2013-12-19');
insert into payment_details values(978,24,2000,'failed','2015-07-11'); 复制代码
创建表invoice_details
create table invoice_details
(
invoice_num int,
creation_date datetime,
session_no int,
ccard_no int,
adrss_no int,
primary key(invoice_num),
foreign key(session_no) references user_session_details(session_no),
foreign key(ccard_no) references credit_card_details(ccard_no),
foreign key(adrss_no) references address(adrss_no)
); 复制代码
插入数据
insert into invoice_details values(188,'2014-02-05',11,345,15);
insert into invoice_details values(101,'2014-04-07',10,145,13);
insert into invoice_details values(111,'2015-03-10',03,211,16);
insert into invoice_details values(197,'2015-06-15',09,978,11);
insert into invoice_details values(125,'2014-07-21',08,679,24);
insert into invoice_details values(167,'2015-01-11',15,667,18); 复制代码
创建表order_details
create table order_details
(
order_num int,
payment_no int,
ac_no int,
invoice_num int,
order_date datetime,
total_amt int,
state varchar(30),
primary key(order_num),
foreign key(ac_no) references user_account(ac_no),
foreign key(payment_no) references payment_details(payment_no),
foreign key(invoice_num) references invoice_details(invoice_num)
); 复制代码
插入数据
insert into order_details values(16,80,125,188,'2015-08-14',6000,'placed');
insert into order_details values(18,56,127,111,'2014-05-12',8000,'cancelled');
insert into order_details values(21,67,126,101,'2015-01-10',9000,'cancelled');
insert into order_details values(28,12,129,197,'2015-02-18',4000,'placed');
insert into order_details values(39,78,128,125,'2014-01-16',7000,'placed');
insert into order_details values(38,24,130,167,'2015-06-19',5500,'not placed'); 复制代码
创建表shipping_details
create table shipping_details(
adrss_no int,
order_num int,
invoice_num int,
shipping_no int,
shipping_method varchar(30),
shipping_charge int,
state varchar(30),
shipping_date datetime,
primary key(shipping_no),
foreign key(adrss_no) references address(adrss_no),
foreign key(order_num)references order_details(order_num),
foreign key(invoice_num)references invoice_details(invoice_num)
); 复制代码
插入数据
insert into shipping_details values(13,16,188,109,'EKART',1000,'delivered','2015-09-12');
insert into shipping_details values(15,18,111,105,'FIRST FLIGHT',6000,'cancelled','2014-01-11');
insert into shipping_details values(24,21,101,110,'DHL',2000,'cancelled','2015-04-09');
insert into shipping_details values(16,39,125,111,'EKART',3000,'cancelled','2014-10-15');
insert into shipping_details values(11,38,197,124,'INDIA POST',4000,'delivered','2015-08-14');
insert into shipping_details values(18,28,167,178,'BLUE DART',5000,'delivered','2015-02-18'); 复制代码
创建表order_item_details
create table order_item_details
(
order_item_no int,
quantity int,
order_num int,
shipping_no int,
inven_item_no int,
primary key(order_item_no),
foreign key(order_num) references order_details(order_num),
foreign key(shipping_no) references shipping_details(shipping_no),
foreign key(inven_item_no) references inventory_item_details(inven_item_no)
); 复制代码
插入数据
insert into order_item_details values(111,13,16,109,188);
insert into order_item_details values(112,10,21,105,167);
insert into order_item_details values(189,9,18,110,122);
insert into order_item_details values(127,8,39,124,156);
insert into order_item_details values(199,14,38,178,134);
insert into order_item_details values(146,15,28,111,177); 复制代码
创建表invoice_historycreate table invoice_history
(
invoice_state int,
state_desc varchar(30),
notes varchar(30),
date datetime,
invoice_num int,
foreign key(invoice_num) references invoice_details(invoice_num)
); 复制代码
插入数据
insert into invoice_history values(1,'Valid','Good','2012-09-24',188);
insert into invoice_history values(0,'Invalid','Not good','2015-01-05',101);
insert into invoice_history values(0,'Invalid','Not good','2012-09-11',111);
insert into invoice_history values(1,'valid','Good','2012-09-09',197);
insert into invoice_history values(1,'valid','Good','2012-09-14',167);
insert into invoice_history values(0,'Invalid','Not good','2014-08-24',125); 复制代码
创建表order_items_history
create table order_items_history
(
seq_no int,
amt int,
state varchar(30),
notes varchar(30),
date datetime,
order_item_no int,
primary key (seq_no),
foreign key(order_item_no) references order_item_details(order_item_no)
); 复制代码
插入数据
insert into order_items_history values(10,7000,'Delivered','Good','2014-09-12',111);
insert into order_items_history values(11,8000,'cancelled','not good','2015-05-10',112);
insert into order_items_history values(12,9000,'Cancelled','not good','2014-10-08',127);
insert into order_items_history values(13,5000,'Cancelled','Not good','2015-03-14',189);
insert into order_items_history values(14,6000,'Delivered','Good','2015-06-11',199);
insert into order_items_history values(15,3000,'Delivered','Good','2014-07-13',146); 复制代码
创建表card_details
create table cart_details
(
c_no int,
inven_item_no int,
state varchar(30),
cart_num int,
date datetime,
quantity int,
primary key(c_no),
foreign key(inven_item_no)references inventory_item_details(inven_item_no),
foreign key(cart_num) references shopping_cart_details(cart_num)
); 复制代码
插入数据
insert into cart_details values(1,188,'0',144,'2016-11-15',13);
insert into cart_details values(2,122,'0',178,'2011-03-13',9);
insert into cart_details values(3,167,'1',156,'2015-07-14',10);
insert into cart_details values(4,134,'1',158,'2015-02-15',14);
insert into cart_details value(5,156,'1',161,'2016-06-15',8);
insert into cart_details value(6,177,'1',190,'2015-01-13',15); 复制代码
这样,我们总共按照数据库设计创建了所有14个表。 我们还在这些表中插入了一些数据。
2.转移数据到hdfs
我们现在准备好了数据库。 唯一剩下的就是要对这些数据进行大数据分析。 因此,首先,我们需要将此数据移动到HDFS中。 我们使用Sqoop做到这一点。
我们将实现Sqoop Incremental Import,以便从MySQL逐步将这些数据导入HDFS。
下面是用于逐步将此数据传输到HDFS的Sqoop脚本。 首先,我们将传输MySQL表中存在的数据。 接下来,当MySQL表更新时,我们需要在Sqoop import命令中指定最后一个值,以便将所有新添加的记录导入HDFS。
Sqoop增量导入
传输user_account数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table user_account --target-dir '/ecom/user_account' --incremental append --check-column ac_no -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,将获得作业指标中的“最后一个值选项”。 记下检查列记录的最后一个值,下次要插入一些新数据时,需要提到最后一个值,这里最后一个值是130,我们在Sqoop命令中提到它,如下所示。
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table user_account --target-dir '/ecom/user_account' --incremental append --check-column ac_no --last-value 130 -m 1 --driver com.mysql.jdbc.Driver
复制代码
转移credit_card_details数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table credit_card_details --target-dir '/ecom/credit_card_details' --incremental append --check-column ccard_no -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,将获得作业指标中的“最后一个值选项”,记下检查列记录的最后一个值。 下次要插入新数据时,需要提及最后一个值。 这里的最后一个值是978,我们将在Sqoop命令中提到它,如下所示。
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table credit_card_details --target-dir '/ecom/credit_card_details' --incremental append --check-column ccard_no --last-value 978 -m 1 --driver com.mysql.jdbc.Driver
复制代码
传输address数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table address --target-dir '/ecom/address' --incremental append --check-column adrss_no -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,将获得作业指标中的“最后一个值选项”。 记下检查列记录的最后一个值,下次要插入此新数据时,需要提及最后一个值。 这里,最后一个值是24,我们在Sqoop命令中提到它,如下所示:
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table address --target-dir '/ecom/address' --incremental append --check-column adrss_no --last-value 24 -m 1 --driver com.mysql.jdbc.Driver
复制代码
转移Payment_details数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table payment_details --target-dir '/ecom/payment_details' --incremental append --check-column payment_no -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,将获得作业指标中的“最后一个值选项”。 记下检查列记录的最后一个值,下次要插入此新数据时,需要提及最后一个值。 这里,最后一个值是80,我们在Sqoop命令中提到它,如下所示:
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table payment_details --target-dir '/ecom/payment_details' --incremental append --check-column payment_no --last-value 80 -m 1 --driver com.mysql.jdbc.Driver
复制代码
转移Shipping_details数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table shipping_details --target-dir '/ecom/shipping_details' --incremental append --check-column shipping_no -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,将获得作业指标中的“最后一个值选项”。 记下检查列记录的最后一个值,下次要插入此新数据时,需要提及最后一个值。 这里,最后一个值是178,我们在Sqoop命令中提到它,如下所示:
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table shipping_details --target-dir '/ecom/shipping_details' --incremental append --check-column shipping_no --last-value 178 -m 1 --driver com.mysql.jdbc.Driver
复制代码
转移order_items_history数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table order_items_history --target-dir '/ecom/order_items_history' --incremental append --check-column seq_no -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,您将获得作业指标中的“最后一个值选项”。 记下检查列记录的最后一个值,下次要插入此新数据时,需要提及最后一个值。 这里,最后一个值是15,我们在Sqoop命令中提到它,如下所示:
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table order_items_history --target-dir '/ecom/order_items_history' --incremental append --check-column seq_no --last-value 15 -m 1 --driver com.mysql.jdbc.Driver
复制代码
转移Order_item_details数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table order_item_details --target-dir '/ecom/order_item_details' --incremental append --check-column order_item_no -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,将获得作业指标中的“最后一个值选项”。 记下检查列记录的最后一个值,下次要插入此新数据时,需要提及最后一个值。 这里,最后一个值是199,我们在Sqoop命令中提到它,如下所示:
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table order_item_details --target-dir '/ecom/order_item_details' --incremental append --check-column order_item_no --last-value 199 -m 1 --driver com.mysql.jdbc.Driver
复制代码
转移Order_details数据
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table order_details --target-dir '/ecom/order_details' --incremental append --check-column order_num -m 1 --driver com.mysql.jdbc.Driver
复制代码
运行此作业后,您将获得作业指标中的“最后一个值选项”。 记下检查列记录的最后一个值,下次要插入此新数据时,需要提及最后一个值。 这里,最后一个值是39,我们在Sqoop命令中提到它,如下所示:
sqoop import --connect jdbc:mysql://localhost/ecom --username 'root' --P --table order_details --target-dir '/ecom/order_details' --incremental append --check-column order_num --last-value 39 -m 1 --driver com.mysql.jdbc.Driver
复制代码
我们已经成功导出了分析所需的内容。 您可以在下面的屏幕截图中看到相同的内容:
3.创建Hive外表
让我们看看如何使用Hive分析这些数据。
首先,我们将在Hive中创建一个数据库,如下所示:
create database ecom;
use ecom; 复制代码
我们已经成功创建了数据库,我们也进入了数据库。
现在,我们将在Hive中创建外部表,引用HDFS中存在的数据的位置。 即使数据被更新,我们也可以在Hive中查询更新的数据,因为我们指的是数据的位置。 如果我们也删除了表,我们的数据将出现在该特定目录中。
创建user_account表
create external table user_account(
ac_no int,
user_id STRING,
user_pswd STRING,
date1 string,
no_of_visits int,
no_of_trnsc int,
trnsc_amt int)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LOCATION '/ecom/user_account'; 复制代码
创建order_details表
create external table order_details(
order_num int,
payment_no int,
ac_no int,
invoice_num int,
order_date string,
total_amt int,
state string)
ROW FORMAT delimited
FIELDS TERMINATED BY ','
LOCATION '/ecom/order_details'; 复制代码
创建order_item_details表
create external table order_item_details(
order_item_no int,
quantity int,
order_num int,
shipping_no int,
inven_item_no int)
ROW FORMAT delimited
FIELDS TERMINATED BY ','
LOCATION '/ecom/order_item_details'; 复制代码
创建表order_items_history表
create external table order_items_history(
seq_no int,
amt int,
state string,
notes string,
date1 string,
order_item_no int)
row format delimited
fields terminated by ','
location '/ecom/order_items_history'; 复制代码
创建shipping_details表
create external table shipping_details(
adrss_no int,
order_num int,
invoice_num int,
shipping_no int,
shipping_method string,
shipping_charge int,
state string,
shipping_date string)
row format delimited
fields terminated by ','
location '/ecom/shipping_details'; 复制代码
创建payment_details表
create external table payment_details(
ccard_no int,
payment_no int,
amt int,
state string,
date1 string)
row format delimited
fields terminated by ','
location '/ecom/payment_details'; 复制代码
创建address表
create external table address(
adrss_no int,
name string,
adrss_1 string,
adrss_2 string,
city string,
state string,
zip int)
row format delimited
fields terminated by ','
location '/ecom/address'; 复制代码
创建credit_card_details表
create external table credit_card_details(
ac_no int,
adrss_no int,
ccard_no int,
card_no string,
holder_name string,
expire_date string)
row format delimited
fields terminated by ','
location '/ecom/credit_card_details'; 复制代码
在这里,我们在Hive中创建了分析部分所需的8个表,并且数据也填充到这些表中。 您可以在下面的屏幕截图中看到8个表格:
4.分析数据
1.分别查找各个客户在每个季度购买的各种商品的详细信息。
在这个问题陈述中,我们需要找出各个客户在一年中的每个季度购买的各种商品。 在这里,我们需要从库存中找到item_no,从user_account中找出客户的ac_no,并从项目历史中找到购买的商品的日期。
以下是Hive查询,以查找上述详细信息。
select account.ac_no as ac_no,COLLECT_SET(order_item_details.inven_item_no) as item_no_list,SUM(order_item_details.quantity) as quantity,COLLECT_SET(order_items_history.date1) as order_date from user_account account JOIN order_details details ON (account.ac_no=details.ac_no) JOIN order_item_details ON (details.order_num=order_item_details.order_num) JOIN order_items_history ON (order_item_details.order_item_no=order_items_history.order_item_no) where order_items_history.date1>='2015-05-01' AND order_items_history.date1<='2015-08-31' group by account.ac_no;
复制代码
2.与过去相比,世界上哪个地区的客户数量和购买总量最多。
在此问题陈述中,我们需要找出过去世界上哪个地区拥有更多客户及其总购买量。 为此,我们将在状态上检查详细信息,并找出哪个州拥有多少客户和这些客户的总购买量。
我们可以从地址表中找到有关状态的信息,客户将从user_account表中计算,他们的交易将从user_account表本身计算得出。
下面给出了一个可用于评估上述问题陈述的Hive查询。
select addres.state as state,COLLECT_SET(account.ac_no) as ac_no_list,COUNT(account.ac_no) as count_ac_no,SUM(account.trnsc_amt) as sum_of_amount from user_account account JOIN order_details details ON account.ac_no=details.ac_no JOIN shipping_details ship ON details.order_num=ship.order_num JOIN address addres ON ship.adrss_no=addres.adrss_no group by addres.state;
复制代码
我们可以在下面的屏幕截图中看到结果:
当数据更新时,即使这样,我们也可以在Hive中运行相同的查询,Hive会在Hive中的数据自动更新时为我们提供更新的结果,因为我们已经将数据集位置引用到HDFS中的外部路径。