【Hive】数据类型与文件格式

804 阅读4分钟

这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战

一、基本类型

Hive 支持数据类型如下:

  1. Integers 整型
  • TINYINT -- 1字节的有符号整数
  • SAMLINT -- 2字节的有符号整数
  • INT -- 4字节的有符号整数
  • BIGINT -- 8字节的有符号整数
  1. Floating 浮点数
  • FLOAT -- 单精度浮点数
  • DOUBLE -- 双精度浮点数
  1. Fixed point numbers (定点 DECIMAL)
  • 用户自定义精度定点数, 如数: DECIMAL(10,3)
  1. String types(字符串)
  • STRTIMESTAMP : 时间戳
  • TIMESTAMP WITH LOCAL
  • TIME ZONE : 时间戳,纳秒精度
  • DATE : 日期类型
  1. Boolean(布尔类型)

BOOLEAN : true / false

  1. Binary types(二进制类型)

BINARY : 字节序列

(1)数据类型隐式转换

Hive 中基本数据类型遵循以下层次结构, 按照这个层次结构, 子类型到祖先类型允许隐式转换。

如图:

2020-08-1411:49.png

hive> select '1.0'+2;
OK
3.0
hive> select '1111' > 10;
hive> select 1 > 0.8;

(2)数据类型显式转换

使用 cast 函数进行强制类型转换;

如果强制类型转换失败, 返回 NULL

hive> select cast('1111s' as int);
OK
NULL
hive> select cast('1111' as int);
OK
1111

二、集合数据类型

Hive 支持集合数据类型:

  • array: 有序相同数据类型的集合。 arrays(1, 2)
  • map : key必须是基本数据类型,value不限。 map('a', 1, 'b', 2)
  • struct : 不同类型字段的集合。类似于 C语言的结构体。 struct('1', 1, 1.0)
  • union : 不同类型的元素存储在同一字段的不同行中。create_union(1, 'a', 63)
hive> select array(1,2,3);
OK
[1,2,3]


-- 使用 [] 访问数组元素
hive> select arr[0] from (select array(1,2,3) arr) tmp;
hive> select map('a', 1, 'b', 2, 'c', 3);
OK
{"a":1,"b":2,"c":3}


-- 使用 [] 访问map元素
hive> select mymap["a"] from (select map('a', 1, 'b', 2, 'c', 3) as mymap) tmp;


-- 使用 [] 访问map元素。 key 不存在返回 NULL
hive> select mymap["x"] from (select map('a', 1, 'b', 2, 'c', 3) as mymap) tmp;
NULL

hive> select struct('username1', 7, 1288.68);
OK
{"col1":"username1","col2":7,"col3":1288.68}

-- 给 struct 中的字段命名
hive> select named_struct("name", "username1", "id", 7, "salary", 12880.68);
OK
{"name":"username1","id":7,"salary":12880.68}


-- 使用 列名.字段名 访问具体信息
hive> select userinfo.id
    > from (select named_struct("name", "username1", "id", 7, "salary", 12880.68) userinfo) tmp;
    
    
-- union 数据类型
hive> select create_union(0, "zhansan", 19, 8000.88) uinfo;

三、文本文件数据编码

Hive 表中的数据在存储在文件系统上, Hive 定义了默认的存储格式, 也支持用户自定义文件存储格式。

Hive 默认使用几个很少出现在字段值中的控制字符, 来表示替换默认分隔符的字符

Hive 默认分隔符 :

id name age hobby(array) score(map)
字段之间:^A
元素之间: ^B
key-value之间:^C
666^Alisi^A18^Aread^Bgame^Ajava^C97^Bhadoop^C87

666
lisi
18
read^Bgame
java^C97^Bhadoop^C87

create table s1(
  id int,
  name string,
  age int,
  hobby array<string>,
  score map<string, int>
);

load data local inpath '/home/hadoop/data/s1.dat' into table s1;
select * from s1;
分隔符名称说明
\n换行符用于分割行。每一行是一条记录,使用换行符分割数据
^A + A用于分割字段。在 CREATE TABLE 语句中使用八进制编码 \001 表示
^B + B用于分隔 ARRATMAPSTRUCT中的元素。在 CREATE TABLE 语句中使用八进制编码 \002 表示
^C + CMapkeyvalue 之间的分隔符。在 CREATE TABLE 语句中使用八进制编码 \003 表示

Hive 中没有定义专门的数据格式, 数据格式可以由用户指定。

用户定义数据格式需要指定三个属性:

  • 列分隔符(通常为空格、"\t"、"\x001")
  • 行分隔符("\n")
  • 读取文件数据的方法

在加载数据的过程中, Hive 不会对数据本身进行任何修改, 而只是将数据内容复制或者移动到相应的 HDFS 目录中。

Hive 数据导出到本地时, 系统默认的分隔符是 ^A、^B、^C 这些特殊字符, 使用 cat 或者 vim 是看不到的;

vi 中输入特殊字符:

  • (Ctrl + v) + (Ctrl + a) => ^A
  • (Ctrl + v) + (Ctrl + b) => ^B
  • (Ctrl + v) + (Ctrl + c) => ^C

^A / ^B / ^C 都是特殊的控制字符, 使用 more 、 cat 命令是看不见的。

可以使用 cat -A file.dat

四、读时模式

  1. RDBMS: 传统数据库中, 在加载时发现数据不符合表的定义, 则拒绝加载数据。 数据在写入数据库时对照表模式进行检查, 这种模式称为 "写时模式" (schema on write)。 写时模式 -> 写数据检查 -> RDBMS;

  2. Hive: Hive 中数据加载过程采用 "读时模式" (schema on read), 加载数据时不进行数据格式的校验, 读取数据时如果不合法则显示NULL。 这种模式的优点是加载数据迅速。 读时模式 -> 读时检查数据 -> Hive;

好处:加载数据快;

问题: 数据显示 NULL