Hive数仓操作(四)

一、Hive 创建表案例一(ARRAY数组类型)

1. 准备数据文件

首先,准备一个名为 stu2.txt 的文件,文件内容示例如下:

复制代码
1001    Alice    fish,cat
1002    Bob      dog,rabbit
1003    Charlie  bird

注意

  • 确保字段之间使用制表符(\t)分隔。
  • 数组元素之间使用逗号(,)分隔。

2. 上传文件到 HDFS

使用以下命令将 stu2.txt 文件上传到 HDFS 指定目录:

bash 复制代码
hadoop fs -put stu2.txt /user/root/a001/

3. 创建 Hive 数据库

为了管理数据,可以创建一个名为 stu 的数据库(如果还未创建):

sql 复制代码
CREATE DATABASE IF NOT EXISTS stu;

4. 使用数据库

切换到刚创建的 stu 数据库:

sql 复制代码
USE stu;

5. 创建 Hive 表

在 Hive 中创建表 stu03,用来存储数据:

sql 复制代码
CREATE TABLE stu03 (
    id INT,
    name STRING,
    hobby ARRAY<STRING>
)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ',';
  • ROW FORMAT DELIMITED: 指定表的行格式为分隔格式。这意味着行中的各个字段是用特定的分隔符来分隔的。
  • FIELDS TERMINATED BY '\t': 指定字段之间的分隔符为制表符(Tab)。这意味着在数据文件中,各个字段是通过制表符来分开。
  • COLLECTION ITEMS TERMINATED BY ',' : 指定数组类型字段(在这里是 hobby)中的各个元素是用逗号分隔的。这意味着在插入数据时,例如 hobby 字段的值可以为 fish,cat,而这两个爱好是通过逗号来分隔的。

6. 加载数据到表中

将 HDFS 中的 stu2.txt 文件中的数据加载到 stu03 表中:

sql 复制代码
LOAD DATA INPATH '/user/root/a001/stu2.txt' INTO TABLE stu03;

7. 测试查询数据

查询所有数据
sql 复制代码
SELECT * FROM stu03;
查询特定字段和处理可能缺失的数组元素
sql 复制代码
SELECT 
    id, 
    name, 
    hobby[0] AS first_hobby, 
    hobby[1] AS second_hobby, 
    NVL(hobby[2], '没有') AS third_hobby
FROM stu03;
查询数组元素个数
sql 复制代码
SELECT 
    id, 
    name, 
    hobby, 
    SIZE(hobby) AS hobby_count 
FROM stu03;

8. 多次查询的示例

在同一条查询中返回多个字段和计算结果:

sql 复制代码
SELECT 
    a.*, 
    SIZE(hobby) AS n, 
    hobby[0] AS h1, 
    hobby[1] AS h2, 
    NVL(hobby[2], 'none') AS h3, 
    NVL(hobby[3], '') AS h4 
FROM stu03 a;

9. 插入新数据

stu03 表中插入一条新数据:

sql 复制代码
INSERT INTO stu03 
VALUES (1005, 'Tom', ARRAY('fish', 'mouse'));

会在/user/hive/warehouse/stu.db/stu03/目录追加生成小文件,如000000_0 ,一般不使用插入操作。


二、Hive 创建表案例二(ARRAY数组类型)

1. 数据文件

假设有一个名为 stu04.txt 的文件:

复制代码
123|华为Mate50|id:1111,token:2222,user_name:zhangsan1
456|华为Mate60|id:1113,token:2224,user_name:zhangsan3
89|小米14|id:1114,token:2225,user_name:zhangsan4
1235|小米13|id:1115,token:2226,user_name:zhangsan5
4562|OPPO A5|id:1116,token:2227,user_name:zhangsan6

2. 创建表

接下来,创建一个包含 map 类型数据的 Hive 表。注意修正语法和格式错误:

sql 复制代码
DROP TABLE IF EXISTS stu03;

CREATE TABLE stu03 (
    sku_id STRING COMMENT '商品id',
    sku_name STRING COMMENT '商品名称',
    state_map MAP<STRING, STRING> COMMENT '商品状态信息'
)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '|'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':';
1). ROW FORMAT DELIMITED
  • 表示该表的行格式是分隔的。也就是说,数据行中的每个字段都是用特定的字符分隔开的。
2). FIELDS TERMINATED BY '|'
  • 指定字段(列)之间的分隔符。在这个例子中,字段之间用 | (竖线)来分隔。
  • 例如,如果一行数据是 123|华为Mate60|id:1111,token:2222,user_name:zhangsan1,那么这个行的三个字段分别是 123华为Mate60id:1111,token:2222,user_name:zhangsan1
3). COLLECTION ITEMS TERMINATED BY ','
  • 这一部分指定了集合类型中的元素(如数组或映射)之间的分隔符。在这个例子中,集合中的元素用 , (逗号)来分隔。
  • 例如,如果某个字段的值是 id:1111,token:2222,user_name:zhangsan1,那么这个字符串被看作一个集合,元素之间用逗号分隔。
4). MAP KEYS TERMINATED BY ':'
  • 这一部分指定了映射类型(即键值对)中键和值之间的分隔符。在这个例子中,键和值用 : (冒号)来分隔。
  • 例如,如果某个字段的值是 id:1111,那么这里的键是 id,值是 1111
示例

结合这些定义,假设我们有以下一行数据:

复制代码
123|华为Mate10|id:1111,token:2222,user_name:zhangsan1
  • 这行数据表示:
    • 第一个字段(商品 ID)是 123
    • 第二个字段(商品名称)是 华为Mate60
    • 第三个字段是一个映射,包含三个键值对:
      • id 的值是 1111
      • token 的值是 2222
      • user_name 的值是 zhangsan1

3. 加载数据

将数据文件加载到刚创建的表中:

sql 复制代码
LOAD DATA LOCAL INPATH '/opt/module/datas/stu04.txt' INTO TABLE stu03;

4. 查询数据

示例查询1
sql 复制代码
SELECT 
    sku_id,
    sku_name,
    state_map 
FROM 
    stu03;
解析
  • sku_id: 选择 SKU 的 ID。
  • sku_name: 选择 SKU 的名称。
  • state_map : 选择整个 state_map 列,这将返回该列的所有内容(键值对)。
结果(只展示了三行)
sku_id sku_name state_map
1 华为Mate50 {"id":"1111", "token":"2222", "user_name":"zhangsan"}
2 华为Mate60 {"id":"1113", "token":"2224", "user_name":"zhangsan2"}
3 小米14 {"id":"1114", "token":"2225", "user_name":"zhangsan3"}
示例查询2:直接提取特定键
sql 复制代码
SELECT 
    sku_id,
    sku_name,
    state_map['id'] AS id,
    state_map['token'] AS token,
    MAP_KEYS(state_map) AS keys,
    MAP_VALUES(state_map) AS values,
    SIZE(state_map) AS number_of_entries 
FROM 
    stu03;
解析
  • state_map['id'] AS id : 从 state_map 中提取 id
  • state_map['token'] AS token : 从 state_map 中提取 token
  • MAP_KEYS(state_map) AS keys : 获取 state_map 中所有的键。
  • MAP_VALUES(state_map) AS values : 获取 state_map 中所有的值。
  • SIZE(state_map) AS number_of_entries : 获取 state_map 中的键值对数量。
结果
sku_id sku_name id token keys values number_of_entries
1 华为Mate50 1111 2222 ["id", "token", "user_name"] ["1111", "2222", "zhangsan"] 3
2 华为Mate60 1113 2224 ["id", "token", "user_name"] ["1113", "2224", "zhangsan2"] 3
3 小米14 1114 2225 ["id", "token", "user_name"] ["1114", "2225", "zhangsan3"] 3
示例查询3:使用 MAP_KEYS 和索引
sql 复制代码
SELECT 
    sku_id,
    sku_name,
    MAP_KEYS(state_map)[0] AS first_key,
    MAP_VALUES(state_map)[0] AS first_value,
    MAP_KEYS(state_map) AS keys,
    MAP_VALUES(state_map) AS values,
    SIZE(state_map) AS number_of_entries 
FROM 
    stu03;
解析
  • MAP_KEYS(state_map)[0] AS first_key : 获取 state_map 中的第一个键。
  • MAP_VALUES(state_map)[0] AS first_value : 获取 state_map 中的第一个值。
  • MAP_KEYS(state_map) AS keys: 获取所有键。
  • MAP_VALUES(state_map) AS values: 获取所有值。
  • SIZE(state_map) AS number_of_entries: 获取键值对数量。
结果

根据相同的 state_map 内容,查询结果将显示如下:

sku_id sku_name first_key first_value keys values number_of_entries
1 华为Mate50 id 1111 ["id", "token", "user_name"] ["1111", "2222", "zhangsan"] 3
2 华为Mate60 id 1113 ["id", "token", "user_name"] ["1113", "2224", "zhangsan2"] 3
3 小米14 id 1114 ["id", "token", "user_name"] ["1114", "2225", "zhangsan3"] 3
相关推荐
枷锁—sha27 分钟前
【PortSwigger Academy】SQL 注入绕过登录 (Login Bypass)
数据库·sql·学习·安全·网络安全
汇智信科32 分钟前
智慧矿山和工业大数据解决方案“智能设备管理系统”
大数据·人工智能·工业大数据·智能矿山·汇智信科·智能设备管理系统
阿里云大数据AI技术1 小时前
Hologres Dynamic Table 在淘天价格力的业务实践
大数据·人工智能·阿里云·hologres·增量刷新
查士丁尼·绵1 小时前
hadoop集群存算分离
hive·hdfs·zookeeper·spark·hbase·yarn·galera
逍遥德2 小时前
PostgreSQL 中唯一约束(UNIQUE CONSTRAINT) 和唯一索引(UNIQUE INDEX) 的核心区别
数据库·sql·postgresql·dba
工业甲酰苯胺2 小时前
字符串分割并展开成表格的SQL实现方法
数据库·sql
科技块儿3 小时前
IP定位技术:游戏反外挂体系中的精准识别引擎
数据库·tcp/ip·游戏
衫水3 小时前
[特殊字符] MySQL 常用指令大全
数据库·mysql·oracle
卓怡学长3 小时前
m115乐购游戏商城系统
java·前端·数据库·spring boot·spring·游戏
小句4 小时前
SQL中JOIN语法详解 GROUP BY语法详解
数据库·sql