表操作
Create: 表创建
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]
譬如当我们希望创建如下的包含
Sr.No | Field Name | Data Type |
---|---|---|
1 | Eid | int |
2 | Name | String |
3 | Salary | Float |
4 | Designation | string |
然后如下的语句会指定该表的注释、不同的域的分隔符、不同的行的分隔符,以及存储的文件类型 |
COMMENT ‘Employee details’
FIELDS TERMINATED BY ‘\t’
LINES TERMINATED BY ‘\n’
STORED IN TEXT FILE
然后完整的创建语句为
hive> CREATE TABLE IF NOT EXISTS employee ( eid int, name String,
salary String, destination String)
COMMENT ‘Employee details’
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘\t’
LINES TERMINATED BY ‘\n’
STORED AS TEXTFILE;
如果你添加了IF NOT EXISTS
选项,
OK
Time taken: 5.905 seconds
hive>
Java Programming
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
public class HiveCreateTable {
private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException {
// Register driver and create driver instance
Class.forName(driverName);
// get connection
Connection con = DriverManager.getConnection("jdbc:hive://localhost:10000/userdb", "", "");
// create statement
Statement stmt = con.createStatement();
// execute statement
stmt.executeQuery("CREATE TABLE IF NOT EXISTS "
+" employee ( eid int, name String, "
+" salary String, destignation String)"
+" COMMENT ‘Employee details’"
+" ROW FORMAT DELIMITED"
+" FIELDS TERMINATED BY ‘\t’"
+" LINES TERMINATED BY ‘\n’"
+" STORED AS TEXTFILE;");
System.out.println(“ Table employee created.”);
con.close();
}
}
内表VS 外表
- 在导入数据到外部表,数据并没有移动到自己的数据仓库目录下
( 如果指定了location 的话) ,也就是说外部表中的数据并不是由它自己来管理的!而内部表则不一样; - 在删除内部表的时候,
Hive 将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive 仅仅删除外部表的元数据,数据是不会删除的! - 在创建内部表或外部表时加上
location 的效果是一样的,只不过表目录的位置不同而已,加上partition 用法也一样,只不过表目录下会有分区目录而已,load data local inpath 直接把本地文件系统的数据上传到hdfs 上,有location 上传到location 指定的位置上,没有的话上传到hive 默认配置的数据仓库中。
内表
create table innertable(id int,name string) row format delimited fields terminated by '|';
然后我们从
load data inpath 'hdfs://master:9000/user/root/test/innerTable' into table innertable;
查看
drop table innertable;
到
create table inner_table_with_p(id int,name string) partitioned by (part_num int);
#从HDFS加载数据
load data inpath 'hdfs://master:9000/user/root/test/innerTable/part1' into table inner_table_with_p partition(part_num=1)(文件夹inner_table_with_p出现子文件夹part_num=1,innerTable中 part1消失);
load data inpath 'hdfs://master:9000/user/root/test/innerTable/part2' into table inner_table_with_p partition(part_num=2)(文件夹inner_table_with_p出现子文件夹part_num=2,innerTable中 part2消失);
load data inpath ‘hdfs://master:9000/user/root/test/innerTable/part3’
外表
加载数据
load data inpath ‘/user/root/test/outerTable/outer’
删除表
加载数据
load data inpath ‘/user/root/test/outerTable/part1’
删除分区
删除表
Partition: 表分区
在
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]
分区创建
单分区
- 创建一个分区表,以
ds 为分区列:
create table invites (id int, name string) partitioned by (ds string) row format delimited fields terminated by 't' stored as textfile;
- 将数据添加到时间为
2013-08-16 这个分区中:
load data local inpath '/home/hadoop/Desktop/data.txt' overwrite into table invites partition (ds='2013-08-16');
- 将数据添加到时间为
2013-08-20 这个分区中:
load data local inpath '/home/hadoop/Desktop/data.txt' overwrite into table invites partition (ds='2013-08-20');
- 从一个分区中查询数据:
select * from invites where ds ='2013-08-12';
- 往一个分区表的某一个分区中添加数据:
insert overwrite table invites partition (ds='2013-08-12') select id,max(name) from test group by id;
可以查看分区的具体情况,使用命令:
hadoop fs -ls /home/hive/warehouse/invites
或者:
show partitions tablename;
Bucket: 桶
对于每一个表
- 获得更高的查询处理效率。桶为表加上了额外的结 构,
Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在( 包含连接列的) 相同列上划分了桶的表,可以使用Map 端连接(Map-side join) 高效的实现。比如JOIN 操作。对于JOIN 操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN 操 作就可以,可以大大较少JOIN 的数据量。 - 使取样
(sampling) 更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
多分区
双分区建表语句:
