hive操作数据表之DML操作
Hive DML 操作:建库、建表、改表、删表,一套 SQL 全搞定
Hive 的 DML 操作跟 MySQL 很像,但有几个关键区别:
- 建表时要指定分隔符(不像 MySQL 已经定义好了)
- 有内表和外表之分(删表时删不删数据,取决于类型)
- 支持分区和分桶(大数据场景下的优化手段)
数据库操作:建库、切库、删库
数据库是表的容器,用来隔离不同业务的数据。
查看已有数据库:
show databases;
创建数据库:
CREATE DATABASE IF NOT EXISTS study_hive
COMMENT '学习 Hive 用的库'
LOCATION '/user/hive/warehouse/study_hive.db';
IF NOT EXISTS:库存在就不重复创建,不报错LOCATION:指定库在 HDFS 上的存放位置(不指定的话默认在/user/hive/warehouse/下)
切换数据库:
USE study_hive;
之后命令行提示符会变成 hive (study_hive)>,表示当前在这个库里操作。
查看数据库详情:
DESC DATABASE study_hive;
-- 输出:库名、注释、HDFS 路径、所有者
删除数据库:
-- 删空库(库里没有表)
DROP DATABASE IF EXISTS study_hive_empty;
-- 删非空库(库里还有表,强制删除)
DROP DATABASE study_hive CASCADE;
CASCADE 会连库带表一起删,操作不可逆,慎用。
创建表:核心是”列定义 + 分隔符 + 存储格式”
建表是 Hive 最常用的操作。语法跟 MySQL 类似,但多了分隔符和存储格式的配置。
基本模板:
CREATE [EXTERNAL] TABLE 表名 (
列名1 类型 COMMENT '注释',
列名2 类型 COMMENT '注释'
)
[PARTITIONED BY (分区列 类型)]
[ROW FORMAT DELIMITED FIELDS TERMINATED BY '分隔符']
[STORED AS 存储格式]
[LOCATION 'HDFS路径'];
一个完整的例子:
CREATE TABLE IF NOT EXISTS user_info (
id INT COMMENT '用户ID',
name STRING COMMENT '姓名',
age INT COMMENT '年龄',
city STRING COMMENT '城市'
)
COMMENT '用户信息表'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',' -- 列之间用逗号分隔
LINES TERMINATED BY '\n' -- 行之间用换行
STORED AS TEXTFILE -- 存成文本文件
LOCATION '/user/hive/warehouse/study_hive.db/user_info';
建表时的两个关键选择:
| 选择 | 选项 | 说明 |
|---|---|---|
| 内表 vs 外表 | EXTERNAL 关键字 |
外表删表不删数据,内表删表删数据 |
| 存储格式 | TEXTFILE / PARQUET / ORC |
文本格式方便看,列式存储查询快 |
内部表 vs 外部表:删表时删不删数据?
这是 Hive 新手最容易搞混的概念。
| 内部表(默认) | 外部表(加 EXTERNAL) |
|
|---|---|---|
| 创建方式 | CREATE TABLE ... |
CREATE EXTERNAL TABLE ... |
| 数据归谁管 | Hive 管 | 用户自己管 |
| 删除表时 | 删元数据 + 删数据 | 只删元数据,数据还在 HDFS 上 |
| 适用场景 | 临时表、中间表 | 原始数据、共享数据 |
什么时候用外表?
数据是别的系统生成的(比如 Flume 采集的日志),Hive 只是拿来查,删表时不能把数据删了。
什么时候用内表?
数据是 Hive 自己产生的(ETL 结果、临时表),删表时数据也不想要了。
查看表是内表还是外表:
DESC FORMATTED user_info;
-- 看 Table Type 那一行:MANAGED_TABLE = 内部表,EXTERNAL_TABLE = 外部表
查看表信息
查看当前库有哪些表:
SHOW TABLES;
查看表结构(列定义):
DESC user_info;
-- 输出列名、类型、注释
查看表的完整信息(存储格式、路径、内外表等):
DESC FORMATTED user_info;
-- 输出包括:表类型、存储格式、HDFS 路径、列信息等
修改表:改表名、加列、改列
1. 改表名:
ALTER TABLE user_info RENAME TO user_detail;
2. 加列:
ALTER TABLE user_detail ADD COLUMNS (
gender STRING COMMENT '性别',
register_date STRING COMMENT '注册日期'
);
3. 改列名/类型:
-- 把 id 改成 user_id
ALTER TABLE user_detail CHANGE COLUMN id user_id INT COMMENT '用户ID';
注意: 改列名不会自动改数据,新旧列名对应关系要清楚。加列后老数据的该列为 NULL,不影响历史数据。
4. 删列(不直接支持):
Hive 没有 DROP COLUMN 语法,想删列要用 REPLACE COLUMNS 覆盖:
ALTER TABLE user_detail REPLACE COLUMNS (
user_id INT,
name STRING
);
-- 只剩两列,其他列被"删"掉了
REPLACE COLUMNS 会改变表的元数据,但不会动 HDFS 上的数据文件。如果数据文件还有”被删列”的数据,读表时会忽略。
删除表:DROP TABLE
DROP TABLE IF EXISTS user_detail;
- 如果是内部表:删元数据 + 删 HDFS 数据
- 如果是外部表:只删元数据,HDFS 数据还在
删表前先用 DESC FORMATTED 看一眼类型,确认是内表还是外表,别把数据意外删了。
常用数据加载方式
建完表后要往里放数据,最常用的两种方式:
方式1:从本地文件加载
LOAD DATA LOCAL INPATH '/home/hadoop/data/user.csv'
OVERWRITE INTO TABLE user_info;
LOCAL:文件在本地(不加则从 HDFS 加载)OVERWRITE:覆盖已有数据(不加则追加)
方式2:从另一张表插入
INSERT OVERWRITE TABLE user_info
SELECT id, name, age, city FROM raw_user;