建表语法(顺序非常重要)
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [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]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
说明:
1、 CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;
用户可以用 IF NOT EXISTS S 选项来忽略这个异常。
2、 EXTERNAL L 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据
的路径( LOCATION)。
Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,
仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的
元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
3、 LIKE 允许用户复制现有的表结构,但是不复制数据。
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table;
4、 ROW FORMAT DELIMITED
[FIELDS TERMINATED BY char]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[LINES TERMINATED BY char] | SERDE serde_name
[WITH SERDEPROPERTIES
(property_name=property_value, property_name=property_value,...)]
hive 建表的时候默认的分割符是'\001',若在建表的时候没有指明分隔符,
load 文件的时候文件的分隔符需要是'\001';若文件分隔符不是'001',程序不会
报错,但表查询的结果会全部为'null';
用 vi 编辑器 Ctrl+v 然后 Ctrl+a 即可输入'\001' -----------> ^A
SerDe 是 Serialize/Deserilize 的简称,目的是用于序列化和反序列化。
Hive 读取文件机制:首先调用 InputFormat(默认 TextInputFormat),返回
一条一条记录(默认是一行对应一条记录)。然后调用SerDe (默认LazySimpleSerDe)
的 Deserializer,将一条记录切分为各个字段(默认'\001')。
Hive 写文件机制:将 Row 写入文件时,主要调用 OutputFormat、SerDe 的
Seriliazer,顺序与读取相反。
可通过 desc formatted 表名;进行相关信息查看。
当我们的数据格式比较特殊的时候,可以自定义 SerDe。
5、 PARTITIONED BY
在 hive Select 查询中一般会扫描整个表内容,会消耗很多时间做没必要的工
作。有时候只需要扫描表中关心的一部分数据,因此建表时引入了 partition 分区
概念。
分区表指的是在创建表时指定的 partition 的分区空间。一个表可以拥有一个
或者多个分区,每个分区以文件夹的形式单独存在表文件夹的目录下。表和列名不
区分大小写。分区是以字段的形式在表结构中存在,通过 e describe table 命令可
以查看到字段存在,但是该字段不存放实际的数据内容,仅仅是分区的表示。
分区表(PARTITIONED BY)
分区建表分为2种,一种是单分区,也就是说在表文件夹目录下只有一级文件夹目录。另外一种是多分区,表文件夹下出现多文件夹嵌套模式。
单分区建表语句:create table day_table (id int, content string) partitioned by (dt string);单分区表,按天分区,在表结构中存在id,content,dt三列。
双分区建表语句:create table day_hour_table (id int, content string) partitioned by (dt string, hour string);双分区表,按天和小时分区,在表结构中新增加了dt和hour两列。
导入数据
LOAD DATA local INPATH '/root/hivedata/dat_table.txt' INTO TABLE day_table partition(dt='2017-07-07');
LOAD DATA local INPATH '/root/hivedata/dat_table.txt' INTO TABLE day_hour_table PARTITION(dt='2017-07-07', hour='08');
基于分区的查询:
SELECT day_table.* FROM day_table WHERE day_table.dt = '2017-07-07';
查看分区:
show partitions day_hour_table;
总的说来partition就是辅助查询,缩小查询范围,加快数据的检索速度和对数据按照一定的规格和条件进行管理。
---------------------------------------------------------------------------------------------------
ROW FORMAT DELIMITED(指定分隔符)
create table day_table (id int, content string) partitioned by (dt string) row format delimited fields terminated by ','; ---指定分隔符创建分区表
复杂类型的数据表指定分隔符
create table complex_array(name string,work_locations array<string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY ',';
数据如下:
zhangsan beijing,shanghai,tianjin,hangzhou
wangwu shanghai,chengdu,wuhan,haerbin
create table t_map(id int,name string,hobby map<string,string>)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':' ;
数据:
1,zhangsan,唱歌:非常喜欢-跳舞:喜欢-游泳:一般般
2,lisi,打游戏:非常喜欢-篮球:不喜欢
----------------------------------------------------------------------------------------------------
内部表、外部表
建内部表
create table student(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',';
建外部表
create external table student_ext(Sno int,Sname string,Sex string,Sage int,Sdept string) row format delimited fields terminated by ',' location '/stu';
内、外部表加载数据:
load data local inpath '/root/hivedata/students.txt' overwrite into table student;
load data inpath '/stu' into table student_ext;
--------------------------
没有分区表的数据 当涉及到where查询的时候 全表扫描 效率低下 浪费资源
分区表 传统的hadoop fs -put已经不能映射成功了 得换一种加载数据方式
LOAD DATA local INPATH '/root/hivedata/a.txt' INTO TABLE t_user2 partition(country='USA');
LOAD DATA local INPATH '/root/hivedata/b.txt' INTO TABLE t_user2 partition(country='CHINA');
关于分区表:
1、是一种更加细致组织文件的形式 把文件划分的更加规范 再进行全表查询的时候 不需要进行全表扫描
2、分区表的字段不能够是表结构中已经存在的字段
3、分区表的现象 在表所在的那个文件夹下面 以分区的字段和分区字段值 再建立一个子文件夹 分区字段=分区值
然后再把对应的结构化数据文件 放在这个文件夹下面
这样的好处就在与 当指定查询某些范围的时候 直接去指定分区下面查询 前提是你分区的字段就是你查询条件
否则还是进行全局扫描
4、虽然select 分区表能够看到分区字段 和分区字段值 但是分区字段是个虚拟的字段 并不真实存在于结构化数据文件当中
create table t_user2(id int,name string,age int) partitioned by (name string) row format delimited fields terminated by ',';
-----------------------
如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,
使用 STORED AS SEQUENCEFILE。
TEXTFILE 是默认的文件格式,使用 D DELIMITED 子句来读取分隔的文件。
6、 CLUSTERED BY INTO num_buckets BUCKETS
对于每一个表(table)或者分,Hive 可以进一步组织成桶,也就是说桶是更为细
粒度的数据范围划分。Hive 也是针对某一列进行桶的组织。Hive 采用对列值哈希,然
后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询
时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,
可以使用 Map 端连接 (Map-side join)高效的实现。比如 JOIN 操作。对于 JOIN 操
作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶
进行 JOIN 操作就可以,可以大大较少 JOIN 的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶
段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
1.2. . 修改表
增加分区:
ALTER TABLE table_name ADD PARTITION (dt='20170101') location
'/user/hadoop/warehouse/table_name/dt=20170101'; //一次添加一个分区
ALTER TABLE table_name ADD PARTITION (dt='2008-08-08', country='us') location
'/path/to/us/part080808' PARTITION (dt='2008-08-09', country='us') location
'/path/to/us/part080809'; //一次添加多个分区
删除分区
ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08');
ALTER TABLE table_name DROP IF EXISTS PARTITION (dt='2008-08-08', country='us');
修改分区
ALTER TABLE table_name PARTITION (dt='2008-08-08') RENAME TO PARTITION (dt='20080808');
添加列
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name STRING);
注: ADD 是代表新增一个字段,新增字段位置在所有列后面 (partition 列前 )
REPLACE 则是表示替换表中所有字段。
修改列
test_change (a int, b int, c int);
ALTER TABLE test_change CHANGE a a1 INT; //修改 a 字段名
// will change column a's name to a1, a's data type to string, and put it after column b. The new
table's structure is: b int, a1 string, c int
ALTER TABLE test_change CHANGE a a1 STRING AFTER b;
// will change column b's name to b1, and put it as the first column. The new table's structure is:
b1 int, a ints, c int
ALTER TABLE test_change CHANGE b b1 INT FIRST;
表重命名
ALTER TABLE table_name RENAME TO new_table_name
1.3. . 显示命令
show tables;
显示当前数据库所有表
show databases |schemas;
显示所有数据库
show partitions table_name;
显示表分区信息,不是分区表执行报错
show functions;
显示当前版本 hive 支持的所有方法
desc extended table_name;
查看表信息
desc formatted table_name;
查看表信息(格式化美观)
describe database database_name;