【大數(shù)據(jù)】Hive DDL 操作與視圖講解
一、概述
Hive是建立在Hadoop上的數(shù)據(jù)倉庫工具,它允許用戶通過類SQL的語法來查詢和管理數(shù)據(jù)。在Hive中,DDL(數(shù)據(jù)定義語言)和視圖操作是非常常見的。
1)表和視圖關(guān)系
表和視圖都是數(shù)據(jù)存儲的邏輯表示方式。它們之間有以下關(guān)系:
- 視圖可以基于一個或多個表創(chuàng)建,而表不可以基于其他表或視圖創(chuàng)建。因此,視圖是從一個或多個表的查詢結(jié)果中獲取數(shù)據(jù)的虛擬表,而表是實際存儲數(shù)據(jù)的物理表。
- 視圖通常用于簡化查詢或隱藏數(shù)據(jù)的復(fù)雜性,可以對基礎(chǔ)表進行查詢過濾、聚合或連接等操作,從而提供更易于理解的結(jié)果。而表則是實際存儲和管理數(shù)據(jù)的物理存儲單元。
- 視圖在定義時不會實際創(chuàng)建物理表,而是保存了一系列查詢語句。在查詢視圖時,Hive會執(zhí)行這些查詢語句并返回結(jié)果。而表則是在定義時就創(chuàng)建了物理存儲單元,并在其中存儲了數(shù)據(jù)。
- 視圖可以簡化數(shù)據(jù)訪問,因為它可以隱藏底層表的復(fù)雜性和細節(jié),讓用戶能夠更容易地對數(shù)據(jù)進行操作和分析。而表可以提供更加靈活和高效的數(shù)據(jù)存儲和訪問方式,因為它們直接存儲數(shù)據(jù)并允許對數(shù)據(jù)進行更廣泛的操作和管理。
總之,表和視圖都是數(shù)據(jù)存儲和管理的方式,它們有各自的優(yōu)點和適用場景。在Hive中,用戶可以根據(jù)實際需要選擇使用表還是視圖來滿足不同的數(shù)據(jù)訪問和管理需求。
2)表與視圖的區(qū)別
在Hive中,表和視圖也是數(shù)據(jù)存儲的邏輯表示方式,但它們之間存在以下區(qū)別:
- 存儲方式:表是實際存儲數(shù)據(jù)的物理表格,而視圖不是存儲數(shù)據(jù)的實體,而是基于查詢結(jié)果生成的虛擬表格。
- 數(shù)據(jù)管理:表可以直接存儲和管理數(shù)據(jù),而視圖只是從一個或多個表的查詢結(jié)果中生成的,它并不實際存儲數(shù)據(jù)。因此,對于大量數(shù)據(jù)的存儲和管理,使用表更為合適;而對于簡化查詢或隱藏數(shù)據(jù)的復(fù)雜性,使用視圖更為合適。
- 數(shù)據(jù)修改:對于表,用戶可以隨時對其中的數(shù)據(jù)進行修改、插入或刪除等操作。而對于視圖,用戶只能對其進行查詢,無法對其進行數(shù)據(jù)修改操作。
- 查詢效率:由于視圖僅僅是基于查詢語句生成的虛擬表格,因此查詢視圖時的效率比查詢表要低。尤其是當(dāng)視圖基于多個表時,查詢效率會更低。
總之,在Hive中,表和視圖都有各自的優(yōu)點和適用場景。用戶可以根據(jù)實際需求選擇使用哪種方式來存儲和管理數(shù)據(jù),以及在查詢數(shù)據(jù)時使用哪種方式來提高效率和簡化操作。
二、環(huán)境準備
如果已經(jīng)有了環(huán)境了,可以忽略,如果想快速部署環(huán)境可以參考我這篇文章:通過 docker-compose 快速部署 Hive 詳細教程
# 登錄容器
docker exec -it hive-hiveserver2 bash
# 連接hive
beeline -u jdbc:hive2://hive-hiveserver2:10000 -n hadoop
三、Hive 數(shù)據(jù)類型
Hive支持原始數(shù)據(jù)類型和復(fù)雜類型,原始類型包括數(shù)值型,Boolean,字符串,時間戳。復(fù)雜類型包括數(shù)組,map,struct。
下面是Hive數(shù)據(jù)類型匯總:
四、DDL 操作
1)表的基本語法
在Hive中,你可以使用HiveQL語言來創(chuàng)建表。下面是一些創(chuàng)建表的基本語法:
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [column_constraint_specification] [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]
[SKEWED BY (col_name, col_name, ...) ON ((col_value, col_value, ...), (col_value, col_value, ...), ...) [STORED AS DIRECTORIES]]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
其中,[] 表示可選項,...表示省略的內(nèi)容。
以下是一些常見的參數(shù)解釋:
- TEMPORARY:表示創(chuàng)建一個臨時表。臨時表在會話結(jié)束時自動刪除。
- EXTERNAL:表示創(chuàng)建一個外部表。外部表的數(shù)據(jù)不是存儲在Hive的數(shù)據(jù)倉庫中,而是存儲在Hadoop分布式文件系統(tǒng)中。
- IF NOT EXISTS:表示如果表已經(jīng)存在,則不執(zhí)行創(chuàng)建表操作。
- table_name:表示表的名稱。
- col_name:表示列的名稱。
- data_type:表示列的數(shù)據(jù)類型。
- column_constraint_specification:表示列的約束條件,比如 NOT NULL、UNIQUE等。
- COMMENT:表示列或表的注釋。
- PARTITIONED BY:表示表的分區(qū)列。
- CLUSTERED BY:表示表的分桶列。
- SORTED BY:表示分桶列的排序方式。
- num_buckets:表示分桶的數(shù)量。
- SKEWED BY:表示表的傾斜列。
- STORED AS:表示表的存儲格式,比如TEXTFILE、SEQUENCEFILE等。
### hive文件存儲格式包括以下幾類(STORED AS TEXTFILE):
1.TEXTFILE:按行存儲的文本文件格式。默認為TEXTFILE。
2.SEQUENCEFILE:二進制序列文件格式,其中鍵和值都是可以序列化的任意類型。
3.PARQUET:列式存儲文件格式,支持讀取和寫入列式存儲的數(shù)據(jù)。
4.ORC:高效列式存儲文件格式,具有高壓縮率和高性能的特點。
5.AVRO:自描述數(shù)據(jù)序列化格式。
6.JSONFILE:按行存儲的JSON文件格式。
#其中TEXTFILE為默認格式,建表時不指定,默認為這個格式,導(dǎo)入數(shù)據(jù)時會直接把數(shù)據(jù)文件拷貝到hdfs上不進行處理。
- TBLPROPERTIES :指定壓縮方式,默認情況下,Hive不會對文件進行壓縮。有以下幾種壓縮方式:
1.SNAPPY:快速壓縮技術(shù),具有較快的壓縮速度和較高的壓縮比。
2.GZIP:廣泛使用的壓縮算法,具有很高的壓縮比,但是較慢。
3.BZIP2:典型的通用文件壓縮算法,具有較高的壓縮比和較慢的壓縮速度。
4.LZO:快速Lempel-Ziv-Oberhumer壓縮算法,具有高壓縮比和快速的壓縮速度。
其中,Hive默認支持的壓縮方式只有GZIP、LZO和Snappy。如果要使用其他壓縮方式,需要在配置文件中手動添加。
例如,我們可以使用以下命令將一張表存儲為ORC文件格式,并使用Snappy壓縮:
CREATE TABLE mytable (
column1 INT,
column2 STRING
)
STORED AS ORC
TBLPROPERTIES ("orc.compress"="SNAPPY");
- LOCATION:表示表的數(shù)據(jù)存儲路徑。只有外部表才能使用 LOCATION 關(guān)鍵字來指定存儲路徑。
關(guān)于分區(qū)和分桶的介紹可以參考我這篇文章:【大數(shù)據(jù)】Hive 分區(qū)和分桶的區(qū)別及示例講解
2)列分隔符和行分隔符
在Hive中,ROW FORMAT DELIMITED 是用于指定表中數(shù)據(jù)的列分隔符和行分隔符的關(guān)鍵字,默認的列分隔符是制表符(Tab鍵),默認的行分隔符是換行符(\n)。
通過指定這些分隔符,用戶可以將不同格式的數(shù)據(jù)導(dǎo)入到Hive表中,并在查詢表時正確地解析數(shù)據(jù)。使用 ROW FORMAT DELIMITED,用戶可以指定以下參數(shù):
- FIELDS TERMINATED BY: 用于指定列分隔符。默認情況下,Hive使用制表符作為列分隔符。用戶可以使用該選項指定自定義的列分隔符,例如逗號、豎線等。
- ESCAPED BY: 用于指定轉(zhuǎn)義字符。如果數(shù)據(jù)中包含列分隔符或行分隔符,則可以使用該選項指定轉(zhuǎn)義字符,以確保這些字符被正確解析。
- LINES TERMINATED BY: 用于指定行分隔符。默認情況下,Hive使用換行符作為行分隔符。用戶可以使用該選項指定自定義的行分隔符,例如換行符、回車符等。
例如,以下是使用 ROW FORMAT DELIMITED 指定逗號作為列分隔符和換行符作為行分隔符來創(chuàng)建一個Hive表的示例:
CREATE TABLE mytable (
id INT,
name STRING,
age INT,
address STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';
3)添加表數(shù)據(jù)方式
1、INSERT 方式
在Hive中,可以使用 INSERT 語句來向表中添加數(shù)據(jù)。Hive支持多種數(shù)據(jù)來源和格式,包括文本文件、CSV文件、JSON文件等。內(nèi)部表(管理表)的數(shù)據(jù)只能通過 INSERT INTO 命令進行插入,而不能直接修改原始數(shù)據(jù)。普通表在被刪除時,會將表中的數(shù)據(jù)一并刪除。
以下是使用 INSERT 語句向Hive表中添加數(shù)據(jù)的基本語法:
INSERT INTO TABLE tablename [PARTITION (partition_column = partition_value, ...)]
[ROW FORMAT row_format]
[STORED AS file_format]
SELECT ...;
- 其中,tablename是要添加數(shù)據(jù)的表的名稱,
- partition_column是要添加數(shù)據(jù)的表的分區(qū)列名稱,
- partition_value是要添加數(shù)據(jù)的表的分區(qū)列值,
- row_format是用于指定輸入數(shù)據(jù)格式的關(guān)鍵字,
- file_format是用于指定輸出數(shù)據(jù)格式的關(guān)鍵字,
- SELECT ...是用于指定要添加到表中的數(shù)據(jù)的查詢語句。
下面是向一個Hive表中添加數(shù)據(jù)的示例:
假設(shè)有一個Hive表mytable,其中包含四個字段:id、name、age和gender,用戶可以使用以下命令向該表中添加數(shù)據(jù):
INSERT INTO mytable VALUES (1, 'Alice', 25, 'F'), (2, 'Bob', 30, 'M'), (3, 'Charlie', 35, 'M');
該命令將向mytable表中插入三行數(shù)據(jù),每行數(shù)據(jù)包含四個字段。
用戶也可以從其他表或查詢結(jié)果中插入數(shù)據(jù)。例如,以下命令從另一個表yourtable中選擇一些數(shù)據(jù)插入到mytable中:
INSERT INTO mytable (id, name, age, gender)
SELECT id, name, age, gender
FROM yourtable
WHERE age > 25;
該命令將從yourtable表中選擇年齡大于25的數(shù)據(jù),并將其插入到mytable表中。
【注意】向Hive表中添加數(shù)據(jù)時,數(shù)據(jù)格式和分隔符需要與表定義中的一致,否則會導(dǎo)致數(shù)據(jù)無法正確解析??梢允褂?nbsp;ROW FORMAT 和FIELDS TERMINATED BY等關(guān)鍵字來指定數(shù)據(jù)格式和分隔符。
2、LOAD DATA方式
使用LOAD DATA語句可以將本地或HDFS上的數(shù)據(jù)加載到Hive表中。具體語法和示例請見下面的示例:
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partition_column = partition_value, ...)]
[ROW FORMAT row_format]
[FIELDS TERMINATED BY field_delim]
[LINES TERMINATED BY line_delim]
[STORED AS file_format];
- 其中,filepath是要加載的數(shù)據(jù)文件路徑,
- tablename是要加載數(shù)據(jù)的表的名稱,
- partition_column是要加載數(shù)據(jù)的表的分區(qū)列名稱,
- partition_value是要加載數(shù)據(jù)的表的分區(qū)列值,
- row_format是用于指定輸入數(shù)據(jù)格式的關(guān)鍵字,
- field_delim是用于指定字段分隔符的字符,
- line_delim是用于指定行分隔符的字符,
- file_format是用于指定輸出數(shù)據(jù)格式的關(guān)鍵字。
【注意】
- 如果使用了 LOCAL 關(guān)鍵字,則表示從本地文件系統(tǒng)加載數(shù)據(jù),否則從HDFS加載數(shù)據(jù)。
- 如果使用了 OVERWRITE 關(guān)鍵字,則表示將數(shù)據(jù)加載到表中時會覆蓋原有數(shù)據(jù)。
例如,以下命令從本地文件系統(tǒng)加載數(shù)據(jù)文件到一個Hive表中:
# 導(dǎo)入本地文件系統(tǒng)文件數(shù)據(jù)到表,LOCAL
LOAD DATA LOCAL INPATH '/path/to/datafile' INTO TABLE mytable;
3、外部表方式
在Hive中,可以創(chuàng)建外部表,這樣可以將數(shù)據(jù)存儲在HDFS或本地文件系統(tǒng)中,并且不會影響到原始數(shù)據(jù)文件。
- 創(chuàng)建外部表:使用 CREATE EXTERNAL TABLE 語句創(chuàng)建外部表,同時指定外部表的表結(jié)構(gòu)和數(shù)據(jù)存儲位置。例如:
CREATE EXTERNAL TABLE mytable (col1 INT, col2 STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/path/to/datafile';
其中,mytable 是外部表的名稱,col1 和 col2 是表的兩個列,ROW FORMAT 和 FIELDS TERMINATED BY 關(guān)鍵字指定了數(shù)據(jù)格式和分隔符,LOCATION 關(guān)鍵字指定了數(shù)據(jù)存儲位置,可以是HDFS或本地文件系統(tǒng)路徑。
- 將數(shù)據(jù)文件復(fù)制到指定位置:將數(shù)據(jù)文件復(fù)制到指定的數(shù)據(jù)存儲位置,例如將數(shù)據(jù)文件復(fù)制到'/path/to/datafile'目錄下。
- 查詢數(shù)據(jù):使用 SELECT 語句查詢數(shù)據(jù)。Hive會自動讀取外部表的數(shù)據(jù)文件并將其解析為表格數(shù)據(jù),然后返回查詢結(jié)果。例如:
SELECT * FROM mytable;
【注意】:
- 創(chuàng)建外部表時,表結(jié)構(gòu)和數(shù)據(jù)存儲位置需要與實際數(shù)據(jù)文件一致,否則查詢結(jié)果可能會不正確。
- 同時,使用外部表方式導(dǎo)入數(shù)據(jù)時,Hive不會移動或修改數(shù)據(jù)文件,因此需要手動將數(shù)據(jù)文件復(fù)制到指定位置,并保證數(shù)據(jù)文件的完整性。
需要注意的是,向Hive表中添加數(shù)據(jù)時,數(shù)據(jù)格式和分隔符需要與表定義中的一致,否則會導(dǎo)致數(shù)據(jù)無法正確解析。可以使用 ROW FORMAT 和FIELDS TERMINATED BY等關(guān)鍵字來指定數(shù)據(jù)格式和分隔符。
4)DDL 常見操作
1、創(chuàng)建表
使用 CREATE TABLE 語句來創(chuàng)建表。
語法:
CREATE TABLE table_name (col1 data_type, col2 data_type, ...)
示例:
CREATE TABLE employee (id INT, name STRING, age INT, salary FLOAT);
# 添加數(shù)據(jù),不建議使用INSERT 效率很低,一般使用LOAD DATA方式導(dǎo)入數(shù)據(jù)
INSERT INTO employee VALUES (1, 'Alice', 25, 5000.00), (2, 'Bob', 30, 6000.00), (3, 'Charlie', 35, 7000.00);
# 導(dǎo)入數(shù)據(jù)(HDFS)
LOAD DATA INPATH '/path/to/input/data' INTO TABLE employee;
2、修改表
使用 ALTER TABLE 語句來修改表結(jié)構(gòu)。
語法:
ALTER TABLE table_name ADD COLUMN col_name data_type
ALTER TABLE table_name DROP COLUMN col_name
ALTER TABLE table_name RENAME TO new_table_name
示例:
ALTER TABLE employee ADD COLUMN gender STRING;
3、刪除表
使用 DROP TABLE 語句來刪除表。
語法:
DROP TABLE table_name
示例:
DROP TABLE employee
4、創(chuàng)建分區(qū)表
用 CREATE TABLE ... PARTITIONED BY 語句來創(chuàng)建分區(qū)表。
語法:
CREATE TABLE table_name (col1 data_type, col2 data_type, ...)
PARTITIONED BY (partition_col1 data_type, partition_col2 data_type, ...)
示例:
CREATE TABLE employee_partitioned (id INT, name STRING, age INT, salary FLOAT)
PARTITIONED BY (gender STRING);
5、創(chuàng)建外部表
用 CREATE EXTERNAL TABLE 語句來創(chuàng)建外部表。
語法:
CREATE EXTERNAL TABLE table_name (col1 data_type, col2 data_type, ...)
LOCATION '/path/to/table'
示例:
CREATE EXTERNAL TABLE employee_external (id INT, name STRING, age INT, salary FLOAT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/user/hive/warehouse/employee_external';
五、視圖操作
1)創(chuàng)建視圖
用 CREATE VIEW 語句來創(chuàng)建視圖。
語法:
CREATE VIEW view_name AS SELECT col1, col2, ... FROM table_name
示例:
CREATE VIEW employee_view AS SELECT id, name, age FROM employee WHERE age > 25;
2)修改視圖
用 ALTER VIEW 語句來修改視圖。
語法:
ALTER VIEW view_name AS SELECT col1, col2, ... FROM table_name WHERE condition
示例:
ALTER VIEW employee_view AS SELECT id, name, age, salary FROM employee WHERE age > 25;
3)刪除視圖
用 DROP VIEW 語句來修改視圖。
語法:
DROP VIEW view_name
示例:
DROP VIEW employee_view;
4)查看視圖定義
用 DESCRIBE VIEW 語句來查看視圖定義。
語法:
DESCRIBE VIEW view_name
示例:
DESCRIBE VIEW employee_view;
總之,Hive中的DDL操作和視圖操作可以幫助用戶定義和管理表、視圖等數(shù)據(jù)結(jié)構(gòu),從而更加靈活和高效地管理和查詢數(shù)據(jù)。用戶可以根據(jù)實際需求選擇使用哪種操作方式,以達到更好的數(shù)據(jù)管理和操作效果。