Hadoop开发--Hive--DDL

一、 DDL 操作

启动服务:

 hive --service metastore &
 hive --service hiveserver2 &

(一)数据库操作

1. 创建数据库

CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
  [COMMENT database_comment]
  [LOCATION hdfs_path]
  [WITH DBPROPERTIES (property_name=property_value, ...)];

默认:创建的数据库将放在hdfs:/user/hive/warehouse
在Hive数据库是一个命名空间或表的集合。
在这里,IF NOT EXISTS是一个可选子句,通知用户已经存在相同名称的数据库。可以使用SCHEMA 在DATABASE的这个命令。下面的查询执行创建一个名为userdb数据库:

0: jdbc:hive2://192.168.71.130:10000> CREATE DATABASE IF NOT EXISTS userdb;
OK
No rows affected (0.139 seconds)

0: jdbc:hive2://192.168.71.130:10000> CREATE SCHEMA IF NOT EXISTS userdb;
OK
No rows affected (0.06 seconds)

下面的查询用于验证数据库列表:

0: jdbc:hive2://192.168.71.130:10000> SHOW DATABASES;
OK
+----------------+
| database_name  |
+----------------+
| default        |
| userdb         |
+----------------+
2 rows selected (0.051 seconds)

数据表存放位置

Hadoop开发--Hive--DDL_第1张图片
数据表存放位置

2. 使用数据库

USE database_name;

0: jdbc:hive2://192.168.71.130:10000> USE userdb;
OK
No rows affected (0.049 seconds)

3. 删除数据库

DROP DATABASE是删除所有的表并删除数据库的语句。它的语法如下:

DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];

假设要删除的数据库名称为userdb。

0: jdbc:hive2://192.168.71.130:10000> DROP DATABASE IF EXISTS userdb;
OK
No rows affected (0.141 seconds)

使用CASCADE查询删除数据库。这意味着要全部删除相应的表在删除数据库之前。

# 在数据库中创建表
0: jdbc:hive2://192.168.71.130:10000> create table employees(name string,sex char(10),age int,salary float,address varchar(50));
OK
No rows affected (0.39 seconds)

0: jdbc:hive2://192.168.71.130:10000> DROP DATABASE IF EXISTS userdb CASCADE;
OK
No rows affected (1.755 seconds)

使用SCHEMA查询删除数据库。

0: jdbc:hive2://192.168.71.130:10000> DROP SCHEMA userdb;

4. 修改数据库

(二)创建表

create Table是用于在Hive中创建表的语句。
语法

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.] table_name

[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[ROW FORMAT row_format]
[STORED AS file_format]

  Hive中的表可以分为托管表外部表,托管表的数据会存储在数据仓库目录下,由Hive管理,外部表的数据在指定位置,不在Hive的数据仓库中,只是在Hive元数据库中注册。
  创建外部表采用create external tablename方式创建,并在创建表的同时指定表的位置。
假设需要使用CREATE TABLE语句创建一个名为employee表。下表列出了employee表中的字段和数据类型:
编号 字段名称 数据类型
1 Eid int
2 Name String
3 Salary Float
4 Designation string

Eid 编号
Name 员工姓名
Salary 工资
Designation 任命管理人员

1. 创建托管表

CREATE TABLE IF NOT EXISTS employee ( eid int, name String,salary String, destination String)
COMMENT '员工信息'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;

说明:
字段分隔符为:\t
行分隔为 \n
存储类型为:textfile

保存文件类型:
文件类型为:textfile

create table users(id int) stored as textfile;

表注释:

COMMENT 'Employee details'
# 表注释
create table users(id int) comment 'users table';

2. 外部表

可以使用关键字EXTERNAL和LOCATION创建不存储在默认位置中的表,其中LOCATION指定了表存在HDFS上的位置。外部表在LOCATION已经存在数据时会派上用场,当删除一个EXTERNAL表时,表中的数据不会在文件系统删除

现在HDFS存在/user/Hadoop/iis/input/iis.log文件,在该位置上创建外部表:

hive>  create external table item(log string) location '/data/input';

hive> select * from users;  

可以看到,Hive将HDFS上的数据直接加载到了表中了。

3. 临时表

表只对当前session有效,session退出后,表自动删除。

CREATE TEMPORARY TABLE IF NOT EXISTS employee ( eid int, name String, salary String, destination String);

insert into employee values(1,'lihaonan','100.3','test')

0: jdbc:hive2://192.168.71.130:10000> select * from employee;
OK
+---------------+----------------+------------------+-----------------------+
| employee.eid  | employee.name  | employee.salary  | employee.destination  |
+---------------+----------------+------------------+-----------------------+
| 1             | lihaonan       | 100.3            | test                  |
+---------------+----------------+------------------+-----------------------+
1 row selected (0.5 seconds)

  1. LIKE创建表
    用Like创建表的语法为:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name  
LIKE existing_table_or_view_name  
[LOCATION hdfs_path];  

Like语法可以精确地根据现存表的定义定义目标表(不复制数据),如:
创建一个新表,结构与其他一样

hive> create table 新表名 like 原表名;

Hive-0.8.0版本及之后的版本,CREATE TABLE LIKE view_name采用视图的schema创建表,并使用默认的SerDe和文件格式。
SerDe是Serialize/Deserilize的简称,目的是用于序列化和反序列化。
示例:

 create table emp like employee;

  1. create-table-as-select
    可以使用create-table-as-select (CTAS)语句创建表并加载查询结果到表中。该语句的操作是原子性,即直到所有查询结果被加载到表中之前,表对于其他用户是不可见的。所以其他用户要么看见带完整查询结果的表,要么根本看不见表。
    CTAS有CREATE和SELECT两部分,SELECT部分可以是任何被Hive支持的select语句,CREATE采用SELECT部分的schema并且创建带有其它表属性如SerDe和存储格式的目标表。如果SELECT部分没有指定所查询列的别名,目标表的列名将自动分配为_col0, _col1, 和 _col2等,否则按照别名命名目标表的列名。CTAS有几个限制:
    目标表不能是分区表
    目标表不能是外部表
create external table temp as select * from employee; 

目标表不能是list bucketing表
正确示例:

create table temp as select * from employee;

(三)修改表

基本语法:
声明接受任意属性,我们希望在一个表中修改以下语法。

ALTER TABLE name RENAME TO new_name
ALTER TABLE name ADD COLUMNS (col_spec[, col_spec ...])
ALTER TABLE name DROP [COLUMN] column_name
ALTER TABLE name CHANGE column_name new_name new_type
ALTER TABLE name REPLACE COLUMNS (col_spec[, col_spec ...])

  1. 重命名表
    Rename To… 语句
    重命名表,把 employee 修改为 emp。
ALTER TABLE employee RENAME TO emp;
  1. 改变列名/类型/位置/注释
    语法:
ALTER TABLE table_name CHANGE
[CLOUMN] col_old_name col_new_name column_type
[CONMMENT col_conmment]
[FIRST|AFTER column_name];

这个命令可以修改表的列名,数据类型,列注释和列所在的位置,FIRST将列放在第一列,AFTER col_name将列放在col_name后面一列。
数据的列名和列数据类型:

# 改变列名
ALTER TABLE employee CHANGE name ename String;
# 改变数据类型
ALTER TABLE employee CHANGE salary salary Double;
  1. 增加/更新列
    基本语法:
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [CONMMENT col_comment], ...);

ADD COLUMNS允许用户在当前列的末尾,分区列之前添加新的列,REPLACE COLUMNS允许用户更新列,更新的过程是先删除当前的列,然后在加入新的列。注:只有在使用native的SerDE时才可以这么做。
增加了一个列名dept在employee表。

ALTER TABLE employee ADD COLUMNS (dept STRING COMMENT 'Department name');
  1. 增加表的属性
# 设置字段分隔属性为逗号
alter table emp set serdeproperties('field.delim'=',');

  1. 修改表文件格式和组织
修改表的文件格式
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;
上面两个命令都修改了表的物理属性。

(四)删除表

语法如下:

DROP TABLE [IF EXISTS] table_name;

以下查询删除一个名为 employee 的表:

DROP TABLE IF EXISTS employee;

  当对一个表进行Drop操作时,不仅会删除表中的数据还会删除表的元数据。如果HDFS配置了Trash,那么删除的数据会移动到.Trash/当前目录下,元数据则会彻底丢失。当删除EXTERNAL表时,表中的数据不会从文件系统中删除,也即文件系统中的数据不会随着EXTERNAL表的删除而删除。当删除被视图应用的表时,不会提示警告信息(视图不再有效,必须被另行删除或者被用户重建)。从Hive-0.7.0开始,DROP操作在表不存在时返回错误,除非使用了IF EXISTS或者配置参数hive.exec.drop.ignorenonexistent被设置为true。

(五)分区表

  就是在系统上建立文件夹,把分类数据放在不同文件夹下面,加快查询速度。
  分区是表的部分列的集合,可以为频繁使用的数据建立分区,这样查找分区中的数据时就不需要扫描全表,这对于提高查找效率很有帮助.
  Hive组织表到分区。它是将一个表到基于分区列,如日期,城市和部门的值相关方式。使用分区,很容易对数据进行部分查询。
  表或分区是细分成桶,以提供额外的结构,可以使用更高效的查询的数据。桶的工作是基于表的一些列的散列函数值。
  一个名为employee表包含雇员数据,如 id, name, dept 和yoj (即入职年份)。假设需要检索所有在2012年加入,查询搜索整个表所需的信息员工的详细信息。但是,如果用年份分区雇员数据并将其存储在一个单独的文件,它减少了查询处理时间。

1. 添加分区

可以通过添加分区表改变所述表。假设我们有一个表叫employee ,拥有如 Id, Name, Salary, Designation, Dept, 和 yoj等字段。
语法:

ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec
[LOCATION 'location1'] partition_spec [LOCATION 'location2'] ...;

partition_spec:
: (p_column = p_col_value, p_column = p_col_value, ...)

以下查询用于将分区添加到employee表。

hive> ALTER TABLE employee  ADD PARTITION (year=’2013’)  location '/2012/part2012';

一个表可以有一个或者多个分区列,Hive将会为分区列上的每个不同的值组合创建单独的数据目录。分区列是虚拟列,要避免分区列名和数据列名相同,可以基于分区列进行查询。

hive> create table people(name string, age int, birthday date, telephone string, address string) partitioned by(name string, age int);  
FAILED: SemanticException [Error 10035]: Column repeated in partitioning columns  

上面出现的错误是因为分区列和数据列名称相同了,此时要么修改数据列名要么修改分区列名。

hive> create table people(name string, age int, birthday date, telephone string, address string) partitioned by(department string, sex string, howOld int);  

建立分区后,会在相应的表目录下建立以分区名命名的目录,目录下是分区的数据。
注意:表中的列不能和partition中的列重合了。

2. 静态分区

Hive分区是在创建表的时候用Partitioned by 关键字定义的,但要注意,Partitioned by子句中定义的列是表中正式的列,但是Hive下的数据文件中并不包含这些列,因为它们是目录名。

create table par_tab (name string,nation string) partitioned by (sex string) row format delimited fields terminated by ',';

1) 导入数据:

准备本地数据文件par_tab.txt,内容 “名字/国籍”,将以性别(sex)作为分区:
把数据插入到表(其实load操作相当于把文件移动到HDFS的Hive目录下):

hive> load data local inpath '/root/par_tab.txt' into table par_tab partition (sex='man');

查询:

hive> select * from par_tab;
徐魁元,china
梁  胜,america
陈  杰,china
张文凯,china
王凯月,japan
尹懋宁,japan

查看par_tab目录结构:

hive> dfs -lsr /user/hive/warehouse/par_tab;

再插入另一个数据文件数据,如文件:

刘丽丽,china
衣  洁,china

hive> load data local inpath '/root/par_tab_wm.txt' into table par_tab partition (sex='woman');

最后查看两次插入的结果,包含了man和woman:

hive> select * from par_tab;

因为分区列是表实际定义的列,所以查询分区数据时:

hive> select * from par_tab where sex='woman';

查看分区内容:

hive> desc par_tab;

2) 多个分区

创建一张静态分区表par_tab_muilt,多个分区(性别+日期):

hive> create table par_tab_muilt (name string, nation string) partitioned by (sex string,dt string) row format delimited fields terminated by ',' ;

导入数据:

hive> load data local inpath '/root/par_tab.txt' into table par_tab_muilt partition (sex='man',dt='2017-03-29');
hive> dfs -lsr /user/hive/warehouse/par_tab_muilt;

新建表的时候定义的分区顺序,决定了文件目录顺序(谁是父目录谁是子目录),正因为有了这个层级关系,当我们查询所有man的时候,man以下的所有日期下的数据都会被查出来。如果只查询日期分区,但父目录sex=man和sex=woman都有该日期的数据,那么Hive会对输入路径进行修剪,从而只扫描日期分区,性别分区不作过滤(即查询结果包含了所有性别)。

2. 动态分区

根据查询得到的数据动态分配到分区里。其实动态分区与静态分区区别就是不指定分区目录,由系统自己选择。

1)启动动态分区功能
hive> set hive.exec.dynamic.partition=true;

假设已有一张表par_tab,前两列是名称name和国籍nation,后两列是分区列,性别sex和日期dt:

hive> select * from par_tab_muilt;

梁  胜  america man     2017-03-29
陈  杰  china   man     2017-03-29
张文凯  china   man     2017-03-29
王凯月  japan   man     2017-03-29
尹懋宁  japan   man     2017-03-29
徐魁元  china   man     2017-03-29

把这张表的内容直接插入到另一张表par_dnm中,并实现sex为静态分区,dt动态分区(不指定到底是哪日,让系统自己分配决定)。

2)创建动态分区

把这张表的内容直接插入到另一张表par_dnm中,并实现sex为静态分区,dt动态分区(不指定到底是哪日,让系统自己分配决定)。
现在我把这张表的内容直接插入到另一张表par_dnm中,并实现sex为静态分区,dt动态分区(不指定到底是哪日,让系统自己分配决定);

hive> insert overwrite table par_dnm partition(sex='man',dt)
    > select name, nation, dt from par_tab_muilt;

插入后看下目录结构,再查看分区数。

hive> show partitions par_dnm;

注意,动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。
动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数hive.exec.dynamic.partition.mode :

hive> set hive.exec.dynamic.partition.mode;
hive.exec.dynamic.partition.mode=strict

它的默认值是strick,即不允许分区列全部是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,但是由于疏忽忘记为主分区列指定值了,这将导致一个dml语句在短时间内创建大量的新的分区(对应大量新的文件夹),对系统性能带来影响。
所以我们要设置:

hive> set hive.exec.dynamic.partition.mode=nostrick;

3. 查看分区结构

hive> show partitions 表名;

4. 重命名分区

语法

ALTER TABLE table_name PARTITION 原分区 RENAME TO PARTITION 新分区;

以下查询用来命名一个分区:

hive> ALTER TABLE employee PARTITION (year=’1203’)
> RENAME TO PARTITION (Yoj=’1203’);

5. 删除分区

删除分区:

ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec, PARTITION partition_spec,...;

以下查询是用来删除分区:

hive> ALTER TABLE employee DROP [IF EXISTS] PARTITION (year=’1203’);

(六)桶表

  桶表是对数据进行哈希取值,然后放到不同文件中存储。
  数据加载到桶表时,会对字段取hash值,然后与桶的数量取模。把数据放到对应的文件中。
  物理上,每个桶就是表(或分区)目录里的一个文件,一个作业产生的桶(输出文件)和reduce任务个数相同。
  可以把表或分区组织成桶,桶是按行分开组织特定字段,每个桶对应一个reduce操作。在建立桶之前,需要设置“hive.enforce.bucketing”属性为true,使Hive能够识别桶。
作用:
桶表专门用于抽样查询,是很专业性的,不是日常用来存储数据的表,需要抽样查询时,才创建和使用桶表。

  1. 启用桶
hive>set hive.enforce.bucketing=true;
hive>set hive.enforce.bucketing;
  1. 创建桶
hive>create table btest2(id int,name string) clustered by(id) into 3 buckets
row format delimited fields terminated by '\t';

向桶中插入数据,这里按照用户id分了三个桶,在插入数据时对应三个reduce操作,输出三个文件。

hive>insert overwrite table btest2 select * from userinfo;

查看数据仓库下的桶目录,三个桶对应三个目录。

hive>dfs –ls /user/hive/warehouse/btest2;

Hive使用对分桶所用的值进行hash,并用hash结果除以桶的个数做取余运算的方式来分桶,保证了每个桶中都有数据,但每个桶中的数据条数不一定相等。

hive>dfs –cat /user/hive/warehouse/btest2/*0_0;
hive>dfs –cat /user/hive/warehouse/btest2/*1_0;
hive>dfs –cat /user/hive/warehouse/btest2/*2_0;

分桶可以获得比分区更高的查询效率,同时分桶也便于对全部数据进行采样处理。

hive>select * from btest2 tablesample(bucket 1 out of 3 on id);
  1. 插入数据
insert table 桶表名 select * from 表名; 

请不要使用Load data插入数据,因为使用load data,没有启动mapreduce对数据进行哈希取值,只是简单的原样导入,没有起到抽样查询的目的。

(七)截断表

基本语法:

TRUNCATE TABLE table_name [PARTITION partition_spec];  
partition_spec:  
  : (partition_col = partition_col_value, partition_col = partiton_col_value, 

当进行truncate操作时将会从一个表或者分区中删除所有的行,用户可以通过指定partition_spec删除多个分区,省略partition_spec将会删除表中的所有分区。
truncate 不能删除外部表!因为外部表里的数据并不是存放在Hive Meta store中.

truncate table 表名;

二、数据类型

1. 列类型

1)字符类型:

字符串类型的数据类型可以使用单引号('')或双引号("")来指定。它包含两个数据类型:VARCHAR和CHAR。Hive遵循C-类型的转义字符。
各种CHAR数据类型:

数据类型 长度
VARCHAR 1 to 65355
CHAR 255
STRING
2)日期类型:
日期

DATE值在年/月/日的格式形式描述 {{YYYY-MM-DD}}.

转换类型 结果
cast(date as date) Same date value
cast(date as string) The year/month/day represented by the Date is formatted as a string in the form ‘YYYY-MM-DD’.
cast(date as timestamp) A timestamp value is generated corresponding to midnight of the year/month/day of the date value, based on the local timezone.
cast(string as date) If the string is in the form ‘YYYY-MM-DD’, then a date value corresponding to that year/month/day is returned. If the string value does not match this formate, then NULL is returned.
cast(timestamp as date) The year/month/day of the timestamp is determined, based on the local timezone, and returned as a date value.
时间戳(timestamp)

它支持传统的UNIX时间戳可选纳秒的精度。它支持的java.sql.Timestamp格式“YYYY-MM-DD HH:MM:SS.fffffffff”和格式“YYYY-MM-DD HH:MM:ss.ffffffffff”。

支持传统的UNIX时间戳和可选的纳秒精度。

  • 支持的转化:
  • 整数数字类型:以秒为单位解释为UNIX时间戳
  • 浮点数值类型:以秒为单位解释为UNIX时间戳,带小数精度
  • 字符串:符合JDBC java.sql.Timestamp格式“YYYY-MM-DD HH:MM:SS.fffffffff”(9位小数位精度)

3)联合类型:

联合是异类的数据类型的集合。可以使用联合创建的一个实例。语法和示例如下:

UNIONTYPE, struct>
{0:1} 
{1:2.0} 
{2:["three","four"]} 
{3:{"a":5,"b":"five"}} 
{2:["six","seven"]} 
{3:{"a":8,"b":"eight"}} 
{0:9} 
{1:10.0}

4) 数值类型

整型

默认情况下,整数型为INT型,当数字大于INT型的范围时,会自动解释执行为BIGINT,或者使用以下后缀进行说明。

类型 后缀 例子
TINYINT Y 100Y
SMALLINT S 100S
BIGINT L 100L

大于BIGINT的数值,需要使用BD后缀以及Decimal(38,0)来处理。

select CAST(18446744073709001000BD AS DECIMAL(38,0)) from dual limit 1;

  Hive的小数型是基于Java BigDecimal做的, BigDecimal在java中用于表示任意精度的小数类型。所有常规数字运算(例如+, - ,*,/)和相关的UDFs(例如Floor,Ceil,Round等等)都使用和支持Decimal。你可以将Decimal和其他数值型互相转换,且Decimal支持科学计数法和非科学计数法。因此,无论您的数据集是否包含如4.004E + 3(科学记数法)或4004(非科学记数法)或两者的组合的数据,可以使用Decimal。
  从Hive 0.13开始,用户可以使用DECIMAL(precision, scale) 语法在创建表时来定义Decimal数据类型的precision和scale。 如果未指定precision,则默认为10。如果未指定scale,它将默认为0(无小数位)。

5) 使用示例

# 创建员工表:
create table employees(name string,sex char(10),age int,salary float,address varchar(50));
OK
No rows affected (0.682 seconds)

# 创建部门表:
create table deptarment(id int,deptname string,joindate date,bonus decimal(10,2));
OK
No rows affected (0.182 seconds)

6) 类型转换函数

# 创建虚表
create table dual(dummy string);
# 必须插入一条记录,否则查不到结果
insert into dual values('1');

cast() 转换函数
对于Date类型的数据,只能在Date、Timestamp以及String之间进行转换。下表将进行详细的说明:

有效的转换 结果
cast(date as date) 返回date类型
cast(timestamp as date) timestamp中的年/月/日的值是依赖与当地的时区,结果返回date类型
cast(string as date) 如果string是YYYY-MM-DD格式的,则相应的年/月/日的date类型的数据将会返回;但如果string不是YYYY-MM-DD格式的,结果则会返回NULL。
cast(date as timestamp) 基于当地的时区,生成一个对应date的年/月/日的时间戳值
cast(date as string) date所代表的年/月/日时间将会转换成YYYY-MM-DD的字符串。

字符串转为float:

0: jdbc:hive2://192.168.71.130:10000> select cast(salary as float) from employee;
OK
+---------+
| salary  |
+---------+
| 100.3   |
+---------+
1 row selected (0.307 seconds)

7) Null 值

缺少值通过特殊值 - NULL表示。

2. 复杂类型

复杂类型包括ARRAY,MAP,STRUCT,UNION,这些复杂类型是由基础类型组成的。
ARRAY:ARRAY类型是由一系列相同数据类型的元素组成,这些元素可以通过下标来访问。比如有一个ARRAY类型的变量fruits,它是由['apple','orange','mango']组成,那么我们可以通过fruits[1]来访问元素orange,因为ARRAY类型的下标是从0开始的;
MAP:MAP包含key->value键值对,可以通过key来访问元素。比如”userlist”是一个map类型,其中username是key,password是value;那么我们可以通过userlist['username']来得到这个用户对应的password;
STRUCT:STRUCT可以包含不同数据类型的元素。这些元素可以通过”点语法”的方式来得到所需要的元素,比如user是一个STRUCT类型,那么可以通过user.address得到这个用户的地址。
UNION: UNIONTYPE,他是从Hive 0.7.0开始支持的。

1). 数组

在Hive 数组与在Java中使用的方法相同。

Syntax: ARRAY

ARRAY是具有相关同类型和名称的变量的集合['John','Doe'] 如:Array(['John','Doe'] )

2). 映射

映射在Hive类似于Java的映射。

Syntax: MAP

MAP是一组键值对集合 字段名[last]获取值 如:map('first','Join','last','Doe')

3). 结构体

在Hive结构体类似于使用复杂的数据。

Syntax: STRUCT

STRUCT列类型为struct{first STRING,last STRING} 如: struct('john','Doe')

4). 示例

name --雇员名,salary --雇员薪水,subordinates --下属员工,deductions --五险一金,个税等,address --雇员的住址

hive> CREATE TABLE employees(name string,salary float,subordinates array,deductions map,address struct);

一个雇员表详细信心存储在一张表中,在RDBMS中则可能存在某个字段的信息存储在另外一张表,通过主外键或查询条件进行连接后获取结果。这里就可以通过一些集合数据类型进行处理了。

三、hive的文件格式

TEXTFILE //文本,默认值
SEQUENCEFILE // 二进制序列文件
RCFILE //列式存储格式文件 Hive0.6以后开始支持
ORC //列式存储格式文件,比RCFILE有更高的压缩比和读写效率,Hive0.11以后开始支持
PARQUET //列出存储格式文件,Hive0.13以后开始支持

四、常见问题:

  1. 分区常见问题
    指定location加载不到数据:
    指定了表的location但是select不出来数据,而目录确实存在hdfs上。
    一个分区一个分区的添加,问题出现的原因是表没有添加到分区,,也就是没有注册,因为数据有可能是之前添加好的再创建表。
    检查是否存在分区:
hive> show partitions 表;  

表指定location的时候,他只是把表的路径指定一个存储位置,原来有的数据他并不知道,之后再添加的数据他知道,就像是注册一下,以前的东西并没有注册,他不知道里面有数据。

msck repair table 表名;

命令就是把location里面的数据都注册一遍,包括已经注册过的。

你可能感兴趣的:(Hadoop开发--Hive--DDL)