實例:
建立外部表:
CREATE EXTERNAL TABLE `trojan_controller`(
`key` string COMMENT 'key',
`src` string COMMENT '',
`src_type` string COMMENT '',
`e_detail_type_code` string COMMENT '',
`e_base_type` string COMMENT '',
`e_subtype` string COMMENT '',
`e_detail_type` string COMMENT '',
`e_extend_type` string COMMENT '',
`full_time` string COMMENT '',
`e_date` string COMMENT '',
`e_hour` string COMMENT '',
`src_ip_point` string COMMENT 'IP_',
`src_ip_value` string COMMENT 'IP_',
`src_port` string COMMENT '',
`dst_ip_point` string COMMENT 'IP_',
`dst_ip_value` string COMMENT 'IP_',
`dst_port` string COMMENT '',
`ctrl_flag` string COMMENT '',
`r_value` string COMMENT '',
`src_ip_vest` string COMMENT 'IP',
`src_ip_area` string COMMENT 'IP',
`src_ip_operator` string COMMENT 'IP',
`dst_ip_vest` string COMMENT 'IP',
`dst_ip_area` string COMMENT 'IP',
`dst_ip_operator` string COMMENT 'IP',
`src_ip_longitude` string COMMENT 'IP',
`src_ip_latitude` string COMMENT 'IP',
`dst_ip_longitude` string COMMENT 'IP',
`dst_ip_latitude` string COMMENT 'IP',
`monitor_point_type` string COMMENT '',
`monitor_point_area` string COMMENT '',
`monitor_point_operator` string COMMENT '',
`monitor_physical_point` string COMMENT '',
`monitor_point_net` string COMMENT '',
`monitor_point_gatway` string COMMENT '',
`city` string COMMENT 'sip',
`obj_name` string COMMENT '',
`organization_name` string COMMENT '')
PARTITIONED BY (`ts` string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LOCATION 'hdfs://10.0.1.43/user/hive/warehouse/trojan_controller';
加載數據:
load data local inpath '/data/cncert/@Bot_or_Trojan@#917MT@_C_IP_@20161230000000.txt' overwrite into table trojan_controller PARTITION(ts='20161230');
刪除表:
drop table trojan_controller;
把沒添加進partition的數據,都增加對應的partition。同步源數據信息metadata:
msck repair table trojan_controller;
數據定義 - DDL
(1)建表(CREATE)的語法如下:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS] [ROW FORMAT row_format] [STORED AS file_format] [LOCATION hdfs_path]
上面的一些關鍵字解釋:
- CREATE TABLE 創建一個指定名字的表。如果相同名字的表已經存在,則拋出異常;用戶可以用 IF NOT EXIST 選項來忽略這個異常
- EXTERNAL 關鍵字可以讓用戶創建一個外部表,在建表的同時指定一個指向實際數據的路徑(LOCATION)
- LIKE 允許用戶復制現有的表結構,但是不復制數據
- COMMENT 可以為表與字段增加描述
- ROW FORMAT 用戶在建表的時候可以自定義 SerDe 或者使用自帶的 SerDe。如果沒有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,將會使用自帶的 SerDe。在建表的時候,用戶還需要為表指定列,用戶在指定表的列的同時也會指定自定義的 SerDe,Hive 通過 SerDe 確定表的具體的列的數據。
- STORED AS 如果文件數據是純文本,可以使用 STORED AS TEXTFILE。如果數據需要壓縮,使用 STORED AS SEQUENCE 。
(2)建表(CREATE)
- 創建普通表
- 創建外部表
- 創建分區表
- 創建 Bucket 表
- 創建簡單表:
hive> CREATE TABLE shiyanlou1( id INT, email STRING, name STRING);
- 創建外部表:
hive> CREATE EXTERNAL TABLE shiyanlou2(
id INT,
email STRING,
name STRING
)
LOCATION '/home/hive/external';
和簡單表相比較,可以發現外部表多了external的關鍵字說明以及LOCATION指定外部表存放的路徑(如果沒有LOCATION,Hive將在HDFS上的/user/hive/warehouse文件夾下以外部表的表名創建一個文件夾,並將屬於這個表的數據存放在這里)。
- 創建分區表:
為了避免Hive在查詢時掃描全表,增加沒有必要的消耗,因此在建表時加入partition。
hive> CREATE TABLE shiyanlou3( id INT, email STRING, name STRING ) PARTITIONED BY(sign_date STRING,age INT);
可以看到,我們使用了sign_date 和age 兩個字段作為分區列。但是,我們必須先創建這兩個分區,才能夠使用。
hive> ALTER TABLE shiyanlou3 add partition(sign_date='20160720',age=20);
- 創建 Bucket 表:
Hive中的table可以拆分成partiton,table和partition又可以進一步通過CLUSTERED BY分成更小的文件bucket,這樣使得多個文件可以在map上同時啟動。
首先需要設置環境變量
hive>set hive.enforce.bucketing = true
hive> CREATE TABLE shiyanlou4(
id INT, email STRING, name STRING, age INT ) PARTITIONED BY(sign_date STRING) CLUSTERED BY(id)SORTED BY(age) INTO 5 BUCKETS ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
(3)修改表結構
- 重命名表
- 增加、刪除分區
- 增加、更新列
- 修改列的名字、類型、位置、注釋
- 增加表的元數據信息
- ...
- 復制一個空表
CREATE TABLE empty LIKE shiyanlou3;
- 刪除表
DROP TABLE [IF EXISTS] table_name [RESTRICT|CASCAD];
- 重命名表
ALTER TABLE table_name RENAME TO new_table_name
- 增加、刪除分區
# 增加 ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ... partition_spec: : PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...) # 刪除 ALTER TABLE table_name DROP partition_spec, partition_spec,...
- 增加、更新列
# ADD 是代表新增一字段,字段位置在所有列后面(partition列前) # REPLACE 則是表示替換表中所有字段。 ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
- 修改列的名字、類型、位置、注釋
# 這個命令可以允許改變列名、數據類型、注釋、列位置或者它們的任意組合 ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
- 增加表的元數據信息
# 用戶可以用這個命令向表中增加元數據信息 metadata ALTER TABLE table_name SET TBLPROPERTIES table_properties table_properties: : (property_name = property_value, ...)
- 改變文件格式和組織
ALTER TABLE table_name SET FILEFORMAT file_format ALTER TABLE table_name CLUSTERED BY(col_name, col_name, ...) [SORTED BY(col_name, ...)] INTO num_buckets BUCKETS
- 創建、刪除視圖
# 創建視圖 CREATE VIEW [IF NOT EXISTS] view_name [ (column_name [COMMENT column_comment], ...) ][COMMENT view_comment][TBLPROPERTIES (property_name = property_value, ...)] AS SELECT ... # 刪除視圖 DROP VIEW view_name
- 創建、刪除函數
# 創建函數 CREATE TEMPORARY FUNCTION function_name AS class_name # 刪除函數 DROP TEMPORARY FUNCTION function_name
- 展示、描述語句
# 顯示 表 show tables; # 顯示 數據庫 show databases; # 顯示 函數 show functions; # 描述 表/列 describe [EXTENDED] table_name[DOT col_name]
數據管理操作 - DML
Hive不支持insert語句進行逐條插入,也不支持update修改數據。首先需要在Hive中建好表,再使用load語句將數據導入,數據一旦導入就不可以修改。
(1)加載數據到Hive表
Hive加載數據到表中時,不做任何轉換。加載操作目前只是單純地復制/移動數據文件到Hive表格的對應位置。
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
-
filepath
- 相對路徑,例如:project/data1
- 絕對路徑,例如: /user/hive/project/data1
- 包含模式的完整 URI,例如:hdfs://namenode:9000/user/hive/project/data1
-
LOCAL 關鍵字
- 指定了LOCAL 即本地 load 命令會去查找本地文件系統中的 filepath. 如果發現是相對路徑,則路徑會被解釋為相對於當前用戶的當前路徑。用戶也可以為本地文件指定一個完整的 URI,比如:file:///user/hive/project/data. 此時 load 命令會將 filepath 中的文件復制到目標文件系統中。目標文件系統由表的位置屬性決定。被復制的數據文件移動到表的數據對應的位置。
- 沒有指定LOCAL 如果 filepath 指向的是一個完整的 URI,hive 會直接使用這個 URI. 否則如果沒有指定 schema 或者 authority,Hive 會使用在 hadoop 配置文件中定義的 schema 和 authority,fs.default.name 指定了 Namenode 的 URI. 如果路徑不是絕對的,Hive 相對於 /user/ 進行解釋。 Hive 會將 filepath 中指定的文件內容移動到 table (或者 partition)所指定的路徑中。
-
OVERWRITE
- 使用 OVERWRITE 關鍵字,目標表(或者分區)中的內容(如果有)會被刪除,然后再將 filepath 指向的文件/目錄中的內容添加到表/分區中。如果目標表(分區)已經有一個文件,並且文件名和 filepath 中的文件名沖突,那么現有的文件會被新文件所替代。
-
實例:
hive> LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE pokes;
(2)將查詢結果插入Hive表
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement
- 多插入模式
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2
- 自動分區模式
INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement
(3)將查詢結果寫入HDFS文件系統
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 [ROW FORMAT row_format] [STORED AS file_format] (Note: Only available starting with Hive 0.11.0) SELECT ... FROM ...
- 多插入模式
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
數據寫入文件系統時會進行文本序列化,且每列用 ^A
來區分,\n
換行。如果任何一列不是原始類型,那么這些將會被序列化為 JSON 格式。
(4)從SQL獲取數據插入Hive表
INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)] VALUES values_row [, values_row ...]
value_row 應用為(value [, value ...]),其中value為null或是任意有效的SQL 語句。
數據查詢操作 - DQL
SQL操作:
- 基本的 Select 操作
- 基於 Partition 的查詢
- HAVING 查詢
- Join 查詢
(1)基本的 Select 操作
SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BY col_list] [ CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list] ] [LIMIT number]
- 一個SELECT語句可以是UNION查詢的一部分,也可以是另一個查詢的子查詢。
- table_reference表示的是所查詢的表。
- 表名和列名大小寫敏感。
- 使用 ALL 和 DISTINCT 選項區分對重復記錄的處理。默認是 ALL,表示查詢所有記錄。DISTINCT 表示去掉重復的記錄;
- LIMIT number可以限制查詢的記錄數
- 簡單的查詢例子:
SELECT * FROM shiyanlou
(2)基於 Partition 的查詢
一般 SELECT 查詢會掃描整個表,使用 PARTITIONED BY 子句建表,查詢就可以利用分區剪枝(input pruning)的特性。
Hive 當前的分區剪枝,只有分區斷言出現在離 FROM 子句最近的那個 WHERE 子句中,才會啟用分區剪枝。
下面是兩個例子,page_view根據date分區:
SELECT page_views.* FROM page_views WHERE page_views.date >= '2008-03-01' AND page_views.date <= '2008-03-31'
SELECT page_views.* FROM page_views JOIN dim_users ON (page_views.user_id = dim_users.id AND page_views.date >= '2008-03-01' AND page_views.date <= '2008-03-31')
(3)HAVING 查詢
Hive在0.7.0版本中添加了對HAVING語句的支持,在舊版本的Hive中,使用一個子查詢也可以實現相同的效果。
SELECT col1 FROM t1 GROUP BY col1 HAVING SUM(col2) > 10
等價於
SELECT col1 FROM (SELECT col1, SUM(col2) AS col2sum FROM t1 GROUP BY col1) t2 WHERE t2.col2sum > 10
(4)Join 查詢
Join 的語法如下:
join_table: table_reference JOIN table_factor [join_condition] | table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition | table_reference LEFT SEMI JOIN table_reference join_condition | table_reference CROSS JOIN table_reference [join_condition] (as of Hive 0.10) table_reference: table_factor | join_table table_factor: tbl_name [alias] | table_subquery alias | ( table_references ) join_condition: ON equality_expression ( AND equality_expression )* equality_expression: expression = expression
- hive 只支持等連接(equality joins)、外連接(outer joins)、左半連接(left semi joins)。hive 不支持非相等的 join 條件,因為它很難在 map/reduce job 中實現這樣的條件。而且,hive 可以 join 兩個以上的表。
參考:
https://www.shiyanlou.com/courses/38/labs/772/document
https://cwiki.apache.org/confluence/display/Hive/LanguageManual