1、數(shù)據(jù)庫操作
1.1、創(chuàng)建數(shù)據(jù)庫
create database if not exists myhive;
use myhive;
1.2、查看數(shù)據(jù)庫詳細(xì)信息
desc database myhive;
數(shù)據(jù)庫本質(zhì)上就是在HDFS之上的文件夾。
默認(rèn)數(shù)據(jù)庫的存放路徑是HDFS的:/user/hive/warehouse內(nèi)
1.3、創(chuàng)建數(shù)據(jù)庫并指定hdfs存儲位置
使用location關(guān)鍵字,可以指定數(shù)據(jù)庫在HDFS的存儲路徑。
create database myhive2 location '/myhive2';
1.4、刪除數(shù)據(jù)庫
刪除一個空數(shù)據(jù)庫,如果數(shù)據(jù)庫下面有數(shù)據(jù)表,那么就會報錯
drop database myhive;
強(qiáng)制刪除數(shù)據(jù)庫,包含數(shù)據(jù)庫下面的表一起刪除
drop database myhive2 cascade;
2、數(shù)據(jù)庫表操作
2.1、表分類
Hive中可以創(chuàng)建的表有好幾種類型, 分別是:
- 內(nèi)部表
- 外部表
- 分區(qū)表
- 分桶表
2.2、內(nèi)部表
內(nèi)部表(CREATE TABLE table_name …)
未被external關(guān)鍵字修飾的即是內(nèi)部表, 即普通表。 內(nèi)部表又稱管理表,內(nèi)部表數(shù)據(jù)存儲的位置由hive.metastore.warehouse.dir參數(shù)決定(默認(rèn):/user/hive/warehouse),刪除內(nèi)部表會直接刪除元數(shù)據(jù)(metadata)及存儲數(shù)據(jù),因此內(nèi)部表不適合和其他工具共享數(shù)據(jù)。
2.2.1、創(chuàng)建內(nèi)部表
內(nèi)部表的創(chuàng)建語法就是標(biāo)準(zhǔn)的:CREATE TABLE table_name…
- 創(chuàng)建一個基礎(chǔ)的表
create database if not exists myhive;
use myhive;
create table if not exists stu(id int,name string);
insert into stu values (1,"zhangsan"), (2, "wangwu");
select * from stu;
- 查看表的數(shù)據(jù)存儲
在HDFS上,查看表的數(shù)據(jù)存儲文件
hdfs dfs -ls /user/hive/warehouse/myhive.db/stu
hdfs dfs -cat /user/hive/warehouse/myhive.db/stu/*
2.2.2、數(shù)據(jù)分隔符
可以看到,數(shù)據(jù)在HDFS上也是以明文文件存在的。
奇怪的是, 列ID和列NAME,好像沒有分隔符,而是擠在一起的。
這是因為,默認(rèn)的數(shù)據(jù)分隔符是:”\001”是一種特殊字符,是ASCII值,鍵盤是打不出來
在某些文本編輯器中是顯示為SOH的。
2.2.3、自行指定分隔符
在創(chuàng)建表的時候可以自己決定:
create table if not exists stu2(id int ,name string) row format delimited fields terminated by '\t';
row format delimited fields terminated by ‘\t’:表示以\t分隔
2.2.4、其它創(chuàng)建內(nèi)部表的形式
除了標(biāo)準(zhǔn)的CREATE TABLE table_name的形式創(chuàng)建內(nèi)部表外
我們還可以通過:
- CREATE TABLE table_name as,基于查詢結(jié)果建表
create table stu3 as select * from stu2;
- CREATE TABLE table_name like,基于已存在的表結(jié)構(gòu)建表
create table stu4 like stu2;
- 也可以使用DESC FORMATTED table_name,查看表類型和詳情
DESC FORMATTED stu2;
2.2.5、刪除內(nèi)部表
我們是內(nèi)部表刪除后,數(shù)據(jù)本身也不會保留,讓我們試一試吧。
DROP TABLE table_name,刪除表
drop table stu2;
可以看到,stu2文件夾已經(jīng)不存在了,數(shù)據(jù)被刪除了。
2.3、外部表
外部表(CREATE EXTERNAL TABLE table_name …LOCATION…)
被external關(guān)鍵字修飾的即是外部表, 即關(guān)聯(lián)表。
外部表是指表數(shù)據(jù)可以在任何位置,通過LOCATION關(guān)鍵字指定。 數(shù)據(jù)存儲的不同也代表了這個表在理念是并不是Hive內(nèi)部管理的,而是可以隨意臨時鏈接到外部數(shù)據(jù)上的。
所以,在刪除外部表的時候, 僅僅是刪除元數(shù)據(jù)(表的信息),不會刪除數(shù)據(jù)本身。
內(nèi)部表和外部表
2.3.1、外部表的創(chuàng)建
外部表,創(chuàng)建表被EXTERNAL關(guān)鍵字修飾,從概念是被認(rèn)為并非Hive擁有的表,只是臨時關(guān)聯(lián)數(shù)據(jù)去使用。
創(chuàng)建外部表也很簡單,基于外部表的特性,可以總結(jié)出: 外部表 和 數(shù)據(jù) 是相互獨立的, 即:
- 可以先有表,然后把數(shù)據(jù)移動到表指定的LOCATION中
- 也可以先有數(shù)據(jù),然后創(chuàng)建表通過LOCATION指向數(shù)據(jù)
- 在Linux上創(chuàng)建新文件,test_external.txt,并填入如下內(nèi)容:
先創(chuàng)建外部表,然后移動數(shù)據(jù)
2. 演示先創(chuàng)建外部表,然后移動數(shù)據(jù)到LOCATION目錄
首先檢查:hadoop fs -ls /tmp,確認(rèn)不存在/tmp/test_ext1目錄
hadoop fs -ls /tmp
創(chuàng)建外部表:create external table test_ext1(id int, name string) row format delimited fields terminated by ‘\t’ location ‘/tmp/test_ext1’;
create external table test_ext1(id int, name string) row format delimited fields terminated by '\t' location '/tmp/test_ext1';
可以看到,目錄/tmp/test_ext1被創(chuàng)建
select * from test_ext1,空結(jié)果,無數(shù)據(jù)
上傳數(shù)據(jù): hadoop fs -put test_external.txt /tmp/test_ext1/
select * from test_ext1,即可看到數(shù)據(jù)結(jié)果
hadoop fs -put test_external.txt /tmp/test_ext1/
select * from test_ext1
演示先存在數(shù)據(jù),后創(chuàng)建外部表
hadoop fs -mkdir /tmp/test_ext2
hadoop fs -put test_external.txt /tmp/test_ext2/
create external table test_ext2(id int, name string) row format delimited fields terminated by '\t' location '/tmp/test_ext2';
select * from test_ext2;
2.3.2、刪除外部表
drop table test_ext1;
drop table test_ext2;
可以發(fā)現(xiàn),在Hive中通過show table,表不存在了
但是在HDFS中,數(shù)據(jù)文件依舊保留
2.3.3、內(nèi)外部表轉(zhuǎn)換
ive可以很簡單的通過SQL語句轉(zhuǎn)換內(nèi)外部表。
查看表類型:desc formatted stu;
desc formatted stu;
內(nèi)部表
- 內(nèi)部表轉(zhuǎn)外部表
alter table stu set tblproperties('EXTERNAL'='TRUE');
- 外部表轉(zhuǎn)內(nèi)部表
alter table stu set tblproperties('EXTERNAL'='FALSE');
要注意:(‘EXTERNAL’=‘FALSE’) 或 (‘EXTERNAL’=‘TRUE’)為固定寫法,區(qū)分大小寫?。?!
2.4、數(shù)據(jù)加載和導(dǎo)出
2.4.1、數(shù)據(jù)加載 - LOAD語法
我們使用 LOAD 語法,從外部將數(shù)據(jù)加載到Hive內(nèi),語法如下:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename;
- 建表
CREATE TABLE myhive.test_load(
dt string comment '時間(時分秒)',
user_id string comment '用戶ID',
word string comment '搜索詞',
url string comment '用戶訪問網(wǎng)址'
) comment '搜索引擎日志表' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
- 還沒有數(shù)據(jù)
- 數(shù)據(jù)加載
從本地加載
load data local inpath '/home/hadoop/search_log.txt' into table myhive.test_load;
- 數(shù)據(jù)加載從HDFS上傳
注意,基于HDFS進(jìn)行l(wèi)oad加載數(shù)據(jù),源數(shù)據(jù)文件會消失(本質(zhì)是被移動到表所在的目錄中)
load data inpath '/tmp/search_log.txt' overwrite into table myhive.test_load;
加上overwrite 關(guān)鍵字。相同的數(shù)據(jù)不會追加。
2.4.2、數(shù)據(jù)加載 - INSERT SELECT 語法
除了load加載外部數(shù)據(jù)外,我們也可以通過SQL語句,從其它表中加載數(shù)據(jù)。
語法
將SELECT查詢語句的結(jié)果插入到其它表中,被SELECT查詢的表可以是內(nèi)部表或外部表。
insert into myhive.test_load2 select * from myhive.test_load;
2.4.3、兩種語法的選擇
-
數(shù)據(jù)在本地
推薦 load data local加載。 -
數(shù)據(jù)在HDFS
如果不保留原始文件: 推薦使用LOAD方式直接加載。
如果保留原始文件: 推薦使用外部表先關(guān)聯(lián)數(shù)據(jù),然后通過INSERT SELECT 外部表的形式加載數(shù)據(jù)。 -
數(shù)據(jù)已經(jīng)在表中
只可以INSERT SELECT。
2.4.4、hive表數(shù)據(jù)導(dǎo)出 - insert overwrite 方式
將hive表中的數(shù)據(jù)導(dǎo)出到其他任意目錄,例如linux本地磁盤,例如hdfs,例如mysql等等
語法:insert overwrite [local] directory ‘path’ select_statement1 FROM from_statement;
- 將查詢的結(jié)果導(dǎo)出到本地 - 使用默認(rèn)列分隔符
insert overwrite local directory '/home/hadoop/export1' select * from test_load ;
- 將查詢的結(jié)果導(dǎo)出到本地 - 指定列分隔符
insert overwrite local directory '/home/hadoop/export2' row format delimited fields terminated by '\t' select * from test_load;
- 將查詢的結(jié)果導(dǎo)出到HDFS上(不帶local關(guān)鍵字)
insert overwrite directory '/tmp/export' row format delimited fields terminated by '\t' select * from test_load;
2.4.5、hive表數(shù)據(jù)導(dǎo)出 - hive shell
基本語法:(hive -f/-e 執(zhí)行語句或者腳本 > file)
bin/hive -e "select * from myhive.test_load;" > /home/hadoop/export3/export4.txt
bin/hive -f export.sql > /home/hadoop/export4/export4.txt
2.5、分區(qū)表
什么是分區(qū)表?
- 可以選擇字段作為表分區(qū)。
- 分區(qū)其實就是HDFS上的不同文件夾。
- 分區(qū)表可以極大的提高特定場景下Hive的操作性能。
在大數(shù)據(jù)中,最常用的一種思想就是分治,我們可以把大的文件切割劃分成一個個的小的文件,這樣每次操作一個小的文件就會很容易了
同樣的道理,在hive當(dāng)中也是支持這種思想的,就是我們可以把大的數(shù)據(jù),按照每天,或者每小時進(jìn)行切分成一個個的小的文件,這樣去操作小的文件就會容易得多了。
同時Hive也支持多個字段作為分區(qū),多分區(qū)帶有層級關(guān)系,如圖
2.5.1、分區(qū)表的使用
基本語法:
create table tablename(...) partitioned by (分區(qū)列 列類型, ......)
row format delimited fields terminated by '';
創(chuàng)建一個分區(qū)表
-- 創(chuàng)建一個分區(qū)表,按照月分區(qū)
create table myhive.score(
name string,
course string,
score int
) partitioned by (month string)
row format delimited fields terminated by '\t';
加載數(shù)據(jù)到分區(qū)
load data local inpath '/home/hadoop/score.txt' into table myhive.score partition(month='202309');
-
9月分區(qū)
-
10月分區(qū)
2.5.2、查hdfs存儲的數(shù)據(jù)
hdfs dfs -ls /user/hive/warehouse/myhive.db/score
hdfs dfs -cat /user/hive/warehouse/myhive.db/score/month=202309/score.txt
2.5.3、多分區(qū)表
根據(jù)年月日分區(qū)
create table myhive.score2(
name string,
course string,
score int
) partitioned by (year string,month string,day string)
row format delimited fields terminated by '\t';
-- 加載數(shù)據(jù)到分區(qū)表中
load data local inpath '/home/hadoop/score.txt'
into table myhive.score2 partition(year='2023',month='09',day='01');
load data local inpath '/home/hadoop/score.txt'
into table myhive.score2 partition(year='2023',month='09',day='02');
select * from myhive.score2;
2.6、分桶表
分桶和分區(qū)一樣,也是一種通過改變表的存儲模式,從而完成對表優(yōu)化的一種調(diào)優(yōu)方式。
但和分區(qū)不同,分區(qū)是將表拆分到不同的子文件夾中進(jìn)行存儲,而分桶是將表拆分到固定數(shù)量的不同文件中進(jìn)行存儲。
2.5.1、分桶表創(chuàng)建
- 開啟分桶的自動優(yōu)化(自動匹配reduce task數(shù)量和桶數(shù)量一致)
set hive.enforce.bucketing=true;
- 創(chuàng)建分桶表
create table course (c_id string,c_name string,t_id string) clustered by(c_id) into 3 buckets row format delimited fields terminated by '\t';
2.5.2、分桶表數(shù)據(jù)加載
桶表的數(shù)據(jù)加載,由于桶表的數(shù)據(jù)加載通過load data無法執(zhí)行,只能通過insert select.
所以,比較好的方式是
- 創(chuàng)建一個臨時表(外部表或內(nèi)部表均可),通過load data加載數(shù)據(jù)進(jìn)入表
-- 創(chuàng)建一個普通表
create table course_temp(
c_id string,
c_name string,
t_id string
) row format delimited fields terminated by '\t';
-- 向普通表加載數(shù)據(jù)
load data local inpath '/home/hadoop/course.txt' into table course_temp;
select * from course_temp;
- 然后通過insert select 從臨時表向桶表插入數(shù)據(jù)
-- 臨時表向course表加載數(shù)據(jù)
insert overwrite table course select * from course_temp cluster by(c_id);
2.5.3、為什么不可以用load data,必須用insert select插入數(shù)據(jù)
如果沒有分桶設(shè)置,插入(加載)數(shù)據(jù)只是簡單的將數(shù)據(jù)放入到:
- 表的數(shù)據(jù)存儲文件夾中(沒有分區(qū))
- 表指定分區(qū)的文件夾中(帶有分區(qū))
一旦有了分桶設(shè)置,比如分桶數(shù)量為3,那么,表內(nèi)文件或分區(qū)內(nèi)數(shù)據(jù)文件的數(shù)量就限定為3
當(dāng)數(shù)據(jù)插入的時候,需要一分為3,進(jìn)入三個桶文件內(nèi)。
問題就在于:如何將數(shù)據(jù)分成三份,劃分的規(guī)則是什么?
- 數(shù)據(jù)的三份劃分基于分桶列的值進(jìn)行hash取模來決定
- 由于load data不會觸發(fā)MapReduce,也就是沒有計算過程(無法執(zhí)行Hash算法),只是簡單的移動數(shù)據(jù)而已,所以無法用于分桶表數(shù)據(jù)插入。
2.5.4、Hash取模
Hash算法是一種數(shù)據(jù)加密算法,其主要特征:
-
同樣的值被Hash加密后的結(jié)果是一致的
比如字符串“hadoop”被Hash后的結(jié)果是12345(僅作為示意),那么無論計算多少次,字符串“hadoop”的結(jié)果都會是12345。比如字符串“bigdata”被Hash后的結(jié)果是56789(僅作為示意),那么無論計算多少次,字符串“bigdata”的結(jié)果都會是56789。
基于如上特征,在輔以有3個分桶文件的基礎(chǔ)上,將Hash的結(jié)果基于3取模(除以3 取余數(shù))
那么,可以得到如下結(jié)果:
- 無論什么數(shù)據(jù),得到的取模結(jié)果均是:0、1、2 其中一個
- 同樣的數(shù)據(jù)得到的結(jié)果一致,如hadoop hash取模結(jié)果是1,無論計算多少次,字符串hadoop的取模結(jié)果都是1。
所以,必須使用insert select的語法,因為會觸發(fā)MapReduce,進(jìn)行hash取模計算。
2.5.5、ash取模確定數(shù)據(jù)歸屬哪個分桶文件
基于Hash取模,數(shù)據(jù)中的每一個分桶列的值,都被hash取模得到0、1、2其中一個數(shù)
基于結(jié)果,存入對應(yīng)序號的桶文件中。
2.5.6、分桶表的性能提升
如果說分區(qū)表的性能提升是:在指定分區(qū)列的前提下,減少被操作的數(shù)據(jù)量,從而提升性能。
分桶表的性能提升就是:基于分桶列的特定操作,如:過濾、JOIN、分組,均可帶來性能提升。
2.7、修改表
2.7.1、表重命名
alter table old_table_name rename to new_table_name;
如:alter table score4 rename to score5;
2.7.2、修改表屬性值
ALTER TABLE table_name SET TBLPROPERTIES table_properties;
table_properties:
: (property_name = property_value, property_name = property_value, … )
如:ALTER TABLE table_name SET TBLPROPERTIES("EXTERNAL"="TRUE"); 修改內(nèi)外部表屬性
如:ALTER TABLE table_name SET TBLPROPERTIES ('comment' = new_comment); 修改表注釋
2.7.3、添加分區(qū)
ALTER TABLE tablename ADD PARTITION (month='201101');
新分區(qū)是空的沒數(shù)據(jù),需要手動添加或上傳數(shù)據(jù)文件
2.7.4、修改分區(qū)值
ALTER TABLE tablename PARTITION (month='202005') RENAME TO PARTITION (month='201105');
2.7.5、刪除分區(qū)
ALTER TABLE tablename DROP PARTITION (month='201105');
2.7.6、添加列
ALTER TABLE table_name ADD COLUMNS (v1 int, v2 string);
2.7.7、修改列名
ALTER TABLE test_change CHANGE v1 v1new INT;
2.7.8、刪除表
DROP TABLE tablename;
2.7.9、清空表
TRUNCATE TABLE tablename;
只可以清空內(nèi)部表
2.8、復(fù)雜類型操作
Hive支持的數(shù)據(jù)類型很多,除了基本的:int、string、varchar、timestamp等
還有一些復(fù)雜的數(shù)據(jù)類型:
- array
數(shù)組類型 - map
映射類型 - struct
結(jié)構(gòu)類型
2.8.1、array類型
如下數(shù)據(jù)文件,有2個列,locations列包含多個城市:
說明:name與locations之間制表符分隔,locations中元素之間逗號分隔
可以使用array數(shù)組類型,存儲locations的數(shù)據(jù)
建表語句:
create table myhive.test_array(name string, work_locations array<string>)
row format delimited fields terminated by '\t'
COLLECTION ITEMS TERMINATED BY ',';
- row format delimited fields terminated by ‘\t’ 表示列分隔符是\t
- COLLECTION ITEMS TERMINATED BY ‘,’ 表示集合(array)元素的分隔符是逗號
導(dǎo)入數(shù)據(jù)
load data local inpath '/home/hadoop/data_for_array_type.txt' overwrite into table myhive.test_array;
常用array類型查詢:
-- 查詢所有數(shù)據(jù)
select * from myhive.test_array;
-- 查詢loction數(shù)組中第一個元素
select name, work_locations[0] location from myhive.test_array;
-- 查詢location數(shù)組中元素的個數(shù)
select name, size(work_locations) location from myhive.test_array;
-- 查詢location數(shù)組中包含tianjin的信息
select * from myhive.test_array where array_contains(work_locations,'tianjin');
2.8.2、Map類型
map類型其實就是簡單的指代:Key-Value型數(shù)據(jù)格式。 有如下數(shù)據(jù)文件,其中members字段是key-value型數(shù)據(jù)
字段與字段分隔符: “,”;需要map字段之間的分隔符:“#”;map內(nèi)部k-v分隔符:“:”
- 建表語句:
create table myhive.test_map(
id int, name string, members map<string,string>, age int
)
row format delimited
fields terminated by ','
COLLECTION ITEMS TERMINATED BY '#'
MAP KEYS TERMINATED BY ':';
MAP KEYS TERMINATED BY ‘:’ 表示key-value之間用:分隔
- 導(dǎo)入數(shù)據(jù)
load data local inpath '/home/hadoop/data_for_map_type.txt' overwrite into table myhive.test_map;
- 常用查詢
# 查詢?nèi)?/span>
select * from myhive.test_map;
# 查詢father、mother這兩個map的key
select id, name, members['father'] father, members['mother'] mother, age from myhive.test_map;
# 查詢?nèi)縨ap的key,使用map_keys函數(shù),結(jié)果是array類型
select id, name, map_keys(members) as relation from myhive.test_map;
# 查詢?nèi)縨ap的value,使用map_values函數(shù),結(jié)果是array類型
select id, name, map_values(members) as relation from myhive.test_map;
# 查詢map類型的KV對數(shù)量
select id,name,size(members) num from myhive.test_map;
# 查詢map的key中有brother的數(shù)據(jù)
select * from myhive.test_map where array_contains(map_keys(members), 'brother');
2.8.3、Struct類型
struct類型是一個復(fù)合類型,可以在一個列中存入多個子列,每個子列允許設(shè)置類型和名稱
有如下數(shù)據(jù)文件,說明:字段之間#分割,struct之間冒號分割
- 建表語句:
create table myhive.test_struct(
id string, info struct<name:string, age:int>
)
row format delimited
fields terminated by '#'
COLLECTION ITEMS TERMINATED BY ':';
- 導(dǎo)入數(shù)據(jù)
load data local inpath '/home/hadoop/data_for_struct_type.txt' into table myhive.test_struct;
- 常用查詢
select * from myhive.test_struct;
-- 直接使用列名.子列名 即可從struct中取出子列查詢
select id, info.name from myhive.test_struct;
2.9、基本查詢
2.9.1、基本語法
查詢語句的基本語法
SELECT [ALL | DISTINCT]select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BYcol_list]
[HAVING where_condition]
[ORDER BYcol_list]
[CLUSTER BYcol_list
| [DISTRIBUTE BY col_list] [SORT BY col_list]
]
[LIMIT number]
整體上和普通SQL差不多,部分有區(qū)別,如:CLUSTER BY、DISTRIBUTE BY、SORT BY等
2.9.2、基本查詢
- 準(zhǔn)備數(shù)據(jù):訂單表
CREATE DATABASE it;
USE it;
CREATE TABLE it.orders (
orderId bigint COMMENT '訂單id',
orderNo string COMMENT '訂單編號',
shopId bigint COMMENT '門店id',
userId bigint COMMENT '用戶id',
orderStatus tinyint COMMENT '訂單狀態(tài) -3:用戶拒收 -2:未付款的訂單 -1:用戶取消 0:待發(fā)貨 1:配送中 2:用戶確認(rèn)收貨',
goodsMoney double COMMENT '商品金額',
deliverMoney double COMMENT '運(yùn)費(fèi)',
totalMoney double COMMENT '訂單金額(包括運(yùn)費(fèi))',
realTotalMoney double COMMENT '實際訂單金額(折扣后金額)',
payType tinyint COMMENT '支付方式,0:未知;1:支付寶,2:微信;3、現(xiàn)金;4、其他',
isPay tinyint COMMENT '是否支付 0:未支付 1:已支付',
userName string COMMENT '收件人姓名',
userAddress string COMMENT '收件人地址',
userPhone string COMMENT '收件人電話',
createTime timestamp COMMENT '下單時間',
payTime timestamp COMMENT '支付時間',
totalPayFee int COMMENT '總支付金額'
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
- 數(shù)據(jù)加載
LOAD DATA LOCAL INPATH '/home/hadoop/itheima_orders.txt' INTO TABLE it.orders;
- 準(zhǔn)備數(shù)據(jù):用戶表
CREATE TABLE it.users (
userId int,
loginName string,
loginSecret int,
loginPwd string,
userSex tinyint,
userName string,
trueName string,
brithday date,
userPhoto string,
userQQ string,
userPhone string,
userScore int,
userTotalScore int,
userFrom tinyint,
userMoney double,
lockMoney double,
createTime timestamp,
payPwd string,
rechargeMoney double
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
- 數(shù)據(jù)加載
LOAD DATA LOCAL INPATH '/home/hadoop/itheima_users.txt' INTO TABLE it.users;
- 查詢所有
SELECT * FROM itheima.orders;
- 查詢單列
SELECT orderid, totalmoney, username, useraddress, paytime FROM itheima.orders;
- 查詢數(shù)據(jù)量
SELECT COUNT(*) FROM itheima.orders;
- 過濾廣東省訂單
SELECT * FROM itheima.orders WHERE useraddress LIKE '%廣東%';
- 找出廣東省單筆營業(yè)額最大的訂單
SELECT * FROM itheima.orders WHERE useraddress like '%廣東%' ORDER BY totalmoney DESC LIMIT 1;
2.9.3、分組、聚合
- 統(tǒng)計未支付、已支付各自的人數(shù)
SELECT ispay, COUNT(*) AS cnt FROM itheima.orders GROUP BY ispay;
- 在已付款訂單中,統(tǒng)計每個用戶最高的一筆消費(fèi)金額
SELECT userid, MAX(totalmoney) AS max_money FROM itheima.orders WHERE ispay = 1 GROUP BY userid;
- 統(tǒng)計每個用戶的平均訂單消費(fèi)額
SELECT userid, AVG(totalmoney) FROM itheima.orders GROUP BY userid;
- 統(tǒng)計每個用戶的平均訂單消費(fèi)額,過濾大于10000的數(shù)據(jù)
SELECT userid, AVG(totalmoney) AS avg_money FROM itheima.orders GROUP BY userid HAVING avg_money > 10000;
2.9.4、JOIN
- JOIN訂單表和用戶表,找出用戶名
SELECT o.orderid, o.userid, u.username, o.totalmoney, o.useraddress, o.paytime FROM itheima.orders o JOIN itheima.users u ON o.userid = u.userid;
- 左外關(guān)聯(lián),訂單表和用戶表,找出用戶名
SELECT o.orderid, o.userid, u.username, o.totalmoney, o.useraddress, o.paytime FROM itheima.orders o LEFT JOIN itheima.users u ON o.userid = u.userid;
2.10、RLIKE 正則匹配
正則表達(dá)式是一種規(guī)則集合,通過特定的規(guī)則字符描述,來判斷字符串是否符合規(guī)則。
RLIKE
Hive中提供RLIKE關(guān)鍵字,可以供用戶使用正則和數(shù)據(jù)進(jìn)行匹配。
我們以上面中使用的訂單表為例,來簡單使用一下RLIKE正則匹配。
- 查找廣東省的數(shù)據(jù)
SELECT * FROM itheima.orders WHERE useraddress RLIKE '.*廣東.*';
- 查找用戶地址是:xx省 xx市 xx區(qū)的數(shù)據(jù)
SELECT * FROM itheima.orders WHERE useraddress RLIKE '..省 ..市 ..區(qū)';
- 查找用戶姓為張、王、鄧
SELECT * FROM itheima.orders WHERE username RLIKE '[張王鄧]\\S+';
- 查找手機(jī)號符合:188*0 規(guī)則
SELECT * FROM itheima.orders WHERE userphone RLIKEE '188\\S{4}0\\S{3}';
2.11、UNION聯(lián)合
UNION 用于將多個 SELECT 語句的結(jié)果組合成單個結(jié)果集。
每個 select 語句返回的列的數(shù)量和名稱必須相同。否則,將引發(fā)架構(gòu)錯誤。
基礎(chǔ)語法:
SELECT ...
UNION [ALL]
SELECT ...
準(zhǔn)備數(shù)據(jù)進(jìn)行測試
- 創(chuàng)建表
CREATE TABLE it.course(
c_id string,
c_name string,
t_id string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
- 加載數(shù)據(jù)
LOAD DATA LOCAL INPATH '/home/hadoop/course.txt' INTO TABLE it.course;
- 聯(lián)合兩個查詢結(jié)果集
SELECT * FROM course WHERE t_id = '周杰輪'
UNION
SELECT * FROM course WHERE t_id = '王力鴻'
2.11.1、UNION聯(lián)合 - 去重
UNION默認(rèn)有去重功能:
- 直接聯(lián)合兩個同樣的查詢結(jié)果
SELECT * FROM course
UNION
SELECT * FROM course
- 如果不需要去重效果
SELECT * FROM course
UNION ALL
SELECT * FROM course
2.11.2、其他寫法
- UNION寫在FROM中
SELECT t_id, COUNT(*) FROM
(
SELECT t_id FROM itheima.course WHERE t_id = '周杰輪'
UNION ALL
SELECT t_id FROM itheima.course WHERE t_id = '王力鴻'
) AS u GROUP BY t_id;
- 用于INSERT SELECT中
CREATE TABLE it.course2 LIKE it.course;
INSERT OVERWRITE TABLE it.course2
SELECT * FROM it.course
UNION ALL
SELECT * FROM it.course;
2.12、Sampling采樣
2.12.1、為什么需要抽樣表數(shù)據(jù)
對表進(jìn)行隨機(jī)抽樣是非常有必要的。
大數(shù)據(jù)體系下,在真正的企業(yè)環(huán)境中,很容易出現(xiàn)很大的表,比如體積達(dá)到TB級別。
對這種表一個簡單的SELECT * 都會非常的慢,哪怕LIMIT 10想要看10條數(shù)據(jù),也會走M(jìn)apReduce流程,這個時間等待是不合適的。
Hive提供的快速抽樣的語法,可以快速從大表中隨機(jī)抽取一些數(shù)據(jù)供用戶查看。
2.12.2、TABLESAMPLE函數(shù)
進(jìn)行隨機(jī)抽樣,本質(zhì)上就是用TABLESAMPLE函數(shù)
語法1,基于隨機(jī)分桶抽樣:
SELECT ... FROM tbl TABLESAMPLE(BUCKET x OUT OF y ON(colname | rand()))
- y表示將表數(shù)據(jù)隨機(jī)劃分成y份(y個桶)
- x表示從y里面隨機(jī)抽取x份數(shù)據(jù)作為取樣
- colname表示隨機(jī)的依據(jù)基于某個列的值
- rand()表示隨機(jī)的依據(jù)基于整行
示例:
SELECT username, orderId, totalmoney FROM itheima.orders TABLESAMPLE(BUCKET 1 OUT OF 10 ON username);
SELECT * FROM itheima.orders TABLESAMPLE(BUCKET 1 OUT OF 10 ON rand());
注意:
- 使用colname作為隨機(jī)依據(jù),則其它條件不變下,每次抽樣結(jié)果一致。
- 使用rand()作為隨機(jī)依據(jù),每次抽樣結(jié)果都不同。
語法2,基于數(shù)據(jù)塊抽樣
SELECT ... FROM tbl TABLESAMPLE(num ROWS | num PERCENT | num(K|M|G));
- num ROWS 表示抽樣num條數(shù)據(jù)。
- num PERCENT 表示抽樣num百分百比例的數(shù)據(jù)。
- num(K|M|G) 表示抽取num大小的數(shù)據(jù),單位可以是K、M、G表示KB、MB、GB。
注意:
- 使用這種語法抽樣,條件不變的話,每一次抽樣的結(jié)果都一致。
- 即無法做到隨機(jī),只是按照數(shù)據(jù)順序從前向后取。
2.13、Virtual Columns 虛擬列
2.13.1、Virtual Columns虛擬列
虛擬列是Hive內(nèi)置的可以在查詢語句中使用的特殊標(biāo)記,可以查詢數(shù)據(jù)本身的詳細(xì)參數(shù)。
Hive目前可用3個虛擬列:
- INPUT__FILE__NAME,顯示數(shù)據(jù)行所在的具體文件
- BLOCK__OFFSET__INSIDE__FILE,顯示數(shù)據(jù)行所在文件的偏移量
- ROW__OFFSET__INSIDE__BLOCK,顯示數(shù)據(jù)所在HDFS塊的偏移量
- 此虛擬列需要設(shè)置:SET hive.exec.rowoffset=true 才可使用
示例:
SELECT *, INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE, ROW__OFFSET__INSIDE__BLOCK FROM it.course;
2.13.2、虛擬列的作用
使用虛擬列,可以讓我們更精準(zhǔn)的查看到具體每一條數(shù)據(jù)在存儲上的詳細(xì)參數(shù)細(xì)節(jié)。
虛擬列不僅僅可以用于SELECT,在WHERE、GROUP BY等均可使用。
如:
SELECT *, BLOCK__OFFSET__INSIDE__FILE FROM course WHERE BLOCK__OFFSET__INSIDE__FILE > 50;
SELECT INPUT__FILE__NAME, COUNT(*) FROM it.orders GROUP BY INPUT__FILE__NAME;
除此以外,在某些錯誤排查場景上,虛擬列可以提供相關(guān)幫助。
3、函數(shù)
官方文檔(https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-MathematicalFunctions)
3.1、分類標(biāo)準(zhǔn)
Hive的函數(shù)分為兩大類:內(nèi)置函數(shù)(Built-in Functions)、用戶定義函數(shù)UDF(User-Defined Functions):
3.2、查看函數(shù)列表
Hive內(nèi)建了不少函數(shù)
使用show functions查看當(dāng)下可用的所有函數(shù);
通過describe function extended funcname來查看函數(shù)的使用方式。
3.3、Mathematical Functions 數(shù)學(xué)函數(shù)
----Mathematical Functions 數(shù)學(xué)函數(shù)-------------
--取整函數(shù): round 返回double類型的整數(shù)值部分 (遵循四舍五入)
select round(3.1415926);
--指定精度取整函數(shù): round(double a, int d) 返回指定精度d的double類型
select round(3.1415926,4);
--取隨機(jī)數(shù)函數(shù): rand 每次執(zhí)行都不一樣 返回一個0到1范圍內(nèi)的隨機(jī)數(shù)
select rand();
--指定種子取隨機(jī)數(shù)函數(shù): rand(int seed) 得到一個穩(wěn)定的隨機(jī)數(shù)序列
select rand(3);
--求數(shù)字的絕對值
select abs(-3);
--得到pi值(小數(shù)點后15位精度)
select pi();
3.4、Collection Functions集合函數(shù)
3.5、Type Conversion Functions類型轉(zhuǎn)換函數(shù)
3.6、Date Functions日期函數(shù)
3.7、Conditional Functions條件函數(shù)
3.8、String Functions字符串函數(shù)
3.9、Data Masking Functions數(shù)據(jù)脫敏函數(shù)
3.10、Misc. Functions其它函數(shù)
4、案例
4.1、需求分析
4.1.1、背景介紹:
聊天平臺每天都會有大量的用戶在線,會出現(xiàn)大量的聊天數(shù)據(jù),通過對聊天數(shù)據(jù)的統(tǒng)計分析,可以更好的對用戶構(gòu)建精準(zhǔn)的用戶畫像,為用戶提供更好的服務(wù)以及實現(xiàn)高ROI的平臺運(yùn)營推廣,給公司的發(fā)展決策提供精確的數(shù)據(jù)支撐。
我們將基于一個社交平臺App的用戶數(shù)據(jù),完成相關(guān)指標(biāo)的統(tǒng)計分析并結(jié)合BI工具對指標(biāo)進(jìn)行可視化展現(xiàn)。
4.1.2、目標(biāo):
基于Hadoop和Hive實現(xiàn)聊天數(shù)據(jù)統(tǒng)計分析,構(gòu)建聊天數(shù)據(jù)分析報表。
4.1.3、需求:
- 統(tǒng)計今日總消息量
- 統(tǒng)計今日每小時消息量、發(fā)送和接收用戶數(shù)
- 統(tǒng)計今日各地區(qū)發(fā)送消息數(shù)據(jù)量
- 統(tǒng)計今日發(fā)送消息和接收消息的用戶數(shù)
- 統(tǒng)計今日發(fā)送消息最多的Top10用戶
- 統(tǒng)計今日接收消息最多的Top10用戶
- 統(tǒng)計發(fā)送人的手機(jī)型號分布情況
- 統(tǒng)計發(fā)送人的設(shè)備操作系統(tǒng)分布情況
4.1.4、數(shù)據(jù)內(nèi)容:
- 數(shù)據(jù)大?。?0萬條數(shù)據(jù)
- 列分隔符:Hive默認(rèn)分隔符’\001’
- 數(shù)據(jù)字典及樣例數(shù)據(jù)
4.1.5、建庫建表
–如果數(shù)據(jù)庫已存在就刪除
drop database if exists db_msg cascade ;
–創(chuàng)建數(shù)據(jù)庫
create database db_msg ;
–切換數(shù)據(jù)庫
use db_msg ;
–列舉數(shù)據(jù)庫
show databases ;
--如果表已存在就刪除
drop table if exists db_msg.tb_msg_source ;
--建表
create table db_msg.tb_msg_source(
msg_time string comment "消息發(fā)送時間",
sender_name string comment "發(fā)送人昵稱",
sender_account string comment "發(fā)送人賬號",
sender_sex string comment "發(fā)送人性別",
sender_ip string comment "發(fā)送人ip地址",
sender_os string comment "發(fā)送人操作系統(tǒng)",
sender_phonetype string comment "發(fā)送人手機(jī)型號",
sender_network string comment "發(fā)送人網(wǎng)絡(luò)類型",
sender_gps string comment "發(fā)送人的GPS定位",
receiver_name string comment "接收人昵稱",
receiver_ip string comment "接收人IP",
receiver_account string comment "接收人賬號",
receiver_os string comment "接收人操作系統(tǒng)",
receiver_phonetype string comment "接收人手機(jī)型號",
receiver_network string comment "接收人網(wǎng)絡(luò)類型",
receiver_gps string comment "接收人的GPS定位",
receiver_sex string comment "接收人性別",
msg_type string comment "消息類型",
distance string comment "雙方距離",
message string comment "消息內(nèi)容"
);
4.1.6、加載數(shù)據(jù)
-
上傳文件到Linux系統(tǒng)
-
load數(shù)據(jù)到表
load data local inpath '/home/hadoop/chat_data-30W.csv' overwrite into table tb_msg_source;
- 驗證結(jié)果
select
msg_time, sender_name, sender_ip, sender_phonetype, receiver_name, receiver_network
from tb_msg_source limit 10;
4.2、ETL數(shù)據(jù)清洗
4.2.1、數(shù)據(jù)清洗
數(shù)據(jù)問題
- 問題1:當(dāng)前數(shù)據(jù)中,有一些數(shù)據(jù)的字段為空,不是合法數(shù)據(jù)
select msg_time, sender_name, sender_gps from
db_msg.tb_msg_source where length(sender_gps) = 0 limit 10;
- 問題2:需求中,需要統(tǒng)計每天、每個小時的消息量,但是數(shù)據(jù)中沒有天和小時字段,只有整體時間字段,不好處理
select msg_time from db_msg.tb_msg_source limit 10;
- 問題3:需求中,需要對經(jīng)度和維度構(gòu)建地區(qū)的可視化地圖,但是數(shù)據(jù)中GPS經(jīng)緯度為一個字段,不好處理
select sender_gps from db_msg.tb_msg_source limit 10;
4.2.2、需求
- 需求1:對字段為空的不合法數(shù)據(jù)進(jìn)行過濾
where過濾 - 需求2:通過時間字段構(gòu)建天和小時字段
date hour函數(shù) - 需求3:從GPS的經(jīng)緯度中提取經(jīng)度和維度
split函數(shù) - 需求4:將ETL以后的結(jié)果保存到一張新的Hive表中
create table db_msg.tb_msg_etl(
msg_time string comment "消息發(fā)送時間",
sender_name string comment "發(fā)送人昵稱",
sender_account string comment "發(fā)送人賬號",
sender_sex string comment "發(fā)送人性別",
sender_ip string comment "發(fā)送人ip地址",
sender_os string comment "發(fā)送人操作系統(tǒng)",
sender_phonetype string comment "發(fā)送人手機(jī)型號",
sender_network string comment "發(fā)送人網(wǎng)絡(luò)類型",
sender_gps string comment "發(fā)送人的GPS定位",
receiver_name string comment "接收人昵稱",
receiver_ip string comment "接收人IP",
receiver_account string comment "接收人賬號",
receiver_os string comment "接收人操作系統(tǒng)",
receiver_phonetype string comment "接收人手機(jī)型號",
receiver_network string comment "接收人網(wǎng)絡(luò)類型",
receiver_gps string comment "接收人的GPS定位",
receiver_sex string comment "接收人性別",
msg_type string comment "消息類型",
distance string comment "雙方距離",
message string comment "消息內(nèi)容",
msg_day string comment "消息日",
msg_hour string comment "消息小時",
sender_lng double comment "經(jīng)度",
sender_lat double comment "緯度"
);
4.2.3、ETL數(shù)據(jù)清洗
- 實現(xiàn)
INSERT OVERWRITE TABLE db_msg.tb_msg_etl
SELECT
*,
day(msg_time) as msg_day,
HOUR(msg_time) as msg_hour,
split(sender_gps, ',')[0] AS sender_lng,
split(sender_gps, ',')[1] AS sender_lat
FROM tb_msg_source WHERE LENGTH(sender_gps) > 0;
- 查看結(jié)果
select msg_time, msy_day, msg_hour, sender_gps, sender_lng, sender_latfrom db_msg.tb_msg_etllimit 10;
4.2.4、擴(kuò)展概念:ETL
其實我們剛剛完成了 從表tb_msg_source 查詢數(shù)據(jù)進(jìn)行數(shù)據(jù)過濾和轉(zhuǎn)換,并將結(jié)果寫入到:tb_msg_etl表中的操作。
這種操作,本質(zhì)上是一種簡單的ETL行為。
ETL:
- E,Extract,抽取
- T,Transform,轉(zhuǎn)換
- L,Load,加載
從A抽取數(shù)據(jù)(E),進(jìn)行數(shù)據(jù)轉(zhuǎn)換過濾(T),將結(jié)果加載到B(L),就是ETL啦。
ETL在大數(shù)據(jù)系統(tǒng)中是非常常見的。
4.3、指標(biāo)計算
- 指標(biāo)1:統(tǒng)計今日消息總量
--保存結(jié)果表
CREATE TABLE IF NOT EXISTS tb_rs_total_msg_cnt
COMMENT "每日消息總量" AS
SELECT
msg_day,
COUNT(*) AS total_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_day;
- 指標(biāo)2:統(tǒng)計每小時消息量、發(fā)送和接收用戶數(shù)
--保存結(jié)果表
CREATE TABLE IF NOT EXISTS tb_rs_hour_msg_cnt
COMMENT "每小時消息量趨勢" AS
SELECT
msg_hour,
COUNT(*) AS total_msg_cnt,
COUNT(DISTINCT sender_account) AS sender_usr_cnt,
COUNT(DISTINCT receiver_account) AS receiver_usr_cnt
FROM db_msg.tb_msg_etl GROUP BY msg_hour;
- 指標(biāo)3:統(tǒng)計今日各地區(qū)發(fā)送消息總量
CREATE TABLE IF NOT EXISTS tb_rs_loc_cnt
COMMENT '今日各地區(qū)發(fā)送消息總量' AS
SELECT
msg_day,
sender_lng,
sender_lat,
COUNT(*) AS total_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_day, sender_lng, sender_lat;
- 指標(biāo)4:統(tǒng)計今日發(fā)送和接收用戶人數(shù)
--保存結(jié)果表
CREATE TABLE IF NOT EXISTS tb_rs_usr_cnt
COMMENT "今日發(fā)送消息人數(shù)、接受消息人數(shù)" AS
SELECT
msg_day,
COUNT(DISTINCT sender_account) AS sender_usr_cnt,
COUNT(DISTINCT receiver_account) AS receiver_usr_cnt
FROM db_msg.tb_msg_etl
GROUP BY msg_day;
- 指標(biāo)5:統(tǒng)計發(fā)送消息條數(shù)最多的Top10用戶
--保存結(jié)果表
CREATE TABLE IF NOT EXISTS db_msg.tb_rs_s_user_top10
COMMENT "發(fā)送消息條數(shù)最多的Top10用戶" AS
SELECT
sender_name AS username,
COUNT(*) AS sender_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_name
ORDER BY sender_msg_cnt DESC
LIMIT 10;
- 指標(biāo)6:統(tǒng)計接收消息條數(shù)最多的Top10用戶
CREATE TABLE IF NOT EXISTS db_msg.tb_rs_r_user_top10
COMMENT "接收消息條數(shù)最多的Top10用戶" AS
SELECT
receiver_name AS username,
COUNT(*) AS receiver_msg_cnt
FROM db_msg.tb_msg_etl
GROUP BY receiver_name
ORDER BY receiver_msg_cnt DESC
LIMIT 10;
- 指標(biāo)7:統(tǒng)計發(fā)送人的手機(jī)型號分布情況
CREATE TABLE IF NOT EXISTS db_msg.tb_rs_sender_phone
COMMENT "發(fā)送人的手機(jī)型號分布" AS
SELECT
sender_phonetype,
COUNT(sender_account) AS cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_phonetype;
- 指標(biāo)8:統(tǒng)計發(fā)送人的手機(jī)操作系統(tǒng)分布
--保存結(jié)果表
CREATE TABLE IF NOT EXISTS db_msg.tb_rs_sender_os
COMMENT "發(fā)送人的OS分布" AS
SELECT
sender_os,
COUNT(sender_account) AS cnt
FROM db_msg.tb_msg_etl
GROUP BY sender_os;
4.4、fineBI安裝與配置
4.4.1、BI概述
BI:Business Intelligence,商業(yè)智能。
指用現(xiàn)代數(shù)據(jù)倉庫技術(shù)、線上分析處理技術(shù)、數(shù)據(jù)挖掘和數(shù)據(jù)展現(xiàn)技術(shù)進(jìn)行數(shù)據(jù)分析以實現(xiàn)商業(yè)價值。
簡單來說,就是借助BI工具,可以完成復(fù)雜的數(shù)據(jù)分析、數(shù)據(jù)統(tǒng)計等需求,為公司決策帶來巨大的價值。
所以,一般提到BI,我們指代的就是工具軟件。常見的BI軟件很多,比如:
- FineBI
- SuperSet
- PowerBI
- TableAu
4.4.2、FineBI的介紹
FineBI的介紹:https://www.finebi.com/
FineBI 是帆軟軟件有限公司推出的一款商業(yè)智能(Business Intelligence)產(chǎn)品。FineBI 是定位于自助大數(shù)據(jù)分析的 BI 工具,能夠幫助企業(yè)的業(yè)務(wù)人員和數(shù)據(jù)分析師,開展以問題導(dǎo)向的探索式分析。
FineBI的特點
- 通過多人協(xié)作來實現(xiàn)最終的可視化構(gòu)建
- 不需要通過復(fù)雜代碼來實現(xiàn)開發(fā),通過可視化操作實現(xiàn)開發(fā)
- 適合于各種數(shù)據(jù)可視化的應(yīng)用場景
- 支持各種常見的分析圖表和各種數(shù)據(jù)源
- 支持處理大數(shù)據(jù)
4.4.3、FineBI的安裝
-
下載:https://www.finebi.com/
-
注冊拿到激活碼
-
安裝軟件,運(yùn)行激活
-
運(yùn)行后會打開一個網(wǎng)頁,設(shè)置用戶名密碼
-
自己使用,選擇內(nèi)置數(shù)據(jù)庫即可
-
fineBI首頁
4.4.4、fineBI配置hive數(shù)據(jù)庫
-
fineBI引入hive驅(qū)動
-
安裝隔離插件
4.4.5、連接數(shù)據(jù)庫
4.5、FineBI可視化展現(xiàn)
4.5.1、同步數(shù)據(jù)
4.5.2、顯示–今日發(fā)送消息人數(shù)、接受消息人數(shù)
-
添加儀表板
-
去掉標(biāo)題
-
切換樣式
-
接受消息人數(shù)
4.5.3、發(fā)送用戶總數(shù)
4.5.4、發(fā)送消息最多的top10(折線雷達(dá)圖)
4.5.5、發(fā)送用戶操作系統(tǒng)占比(餅圖)
4.5.6、各地區(qū)人數(shù)分布(地圖)
4.5.7、接受消息最多的top10(柱狀圖)
4.5.8、發(fā)送人的手機(jī)型號分布(文本)
4.5.8、每小時消息趨勢(多區(qū)折線圖)
文章來源:http://www.zghlxwxcb.cn/news/detail-763123.html
結(jié)束??!
hy:43文章來源地址http://www.zghlxwxcb.cn/news/detail-763123.html
一個勝利者不會放棄,而一個放棄者永遠(yuǎn)不會勝利。
到了這里,關(guān)于hive數(shù)據(jù)庫操作,hive函數(shù),F(xiàn)ineBI可視化操作的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!