标签:刷新 reduce load data 字段名 数据类型转换 store res 数据集 ...
hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
Hive on Spark 和 Hive on Tez
Hive 的结构如图所示
主要分为以下几个部分:
支持的基本类型有
数据类型 | 所占字节 | 开始支持版本 |
---|---|---|
TINYINT | 1byte,-128 ~ 127 | |
SMALLINT | 2byte,-32,768 ~ 32,767 | |
INT | 4byte,-2,147,483,648 ~ 2,147,483,647 | |
BIGINT | 8byte,-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | |
BOOLEAN | ||
FLOAT | 4byte单精度 | |
DOUBLE | 8byte双精度 | |
STRING | ||
BINARY | 从Hive0.8.0开始支持 | |
TIMESTAMP | 从Hive0.8.0开始支持 | |
DECIMAL | 从Hive0.11.0开始支持 | |
CHAR | 从Hive0.13.0开始支持 | |
VARCHAR | 从Hive0.12.0开始支持 | |
DATE | 从Hive0.12.0开始支持 | |
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开始支持的。 |
创建一个复合类型的表
CREATE TABLE employees (
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING, FLOAT>,
address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT>
) PARTITIONED BY (country STRING, state STRING)
创建数据库
CREATE DATABASE [IF NOT EXISTS] userdb
删除数据库
DROP DATABASE [IF EXISTS ]userdb
类型 | 内部表 | 外部表 |
---|---|---|
数据来源 | 与数据库中的 Table 在概念上是类似 | 指向已经在 HDFS 中存在的数据,可以创建 Partition |
数据存放 | 每一个 Table 在 Hive 中都有一个相应的目录存储数据。例如,一个表 test,它在 HDFS 中的路径为:/ warehouse/test。 warehouse是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的数据仓库的目录 | 它和 内部表 在元数据的组织上是相同的,而实际数据的存储则有较大的差异,可以存放于各个不同的目录 |
数据处理 | 所有的 Table 数据都保存在这个目录中,内部表的创建过程和数据加载过程(这两个过程可以在同一个语句中完成),在加载数据的过程中,实际数据会被移动到数据仓库目录中 ,之后对数据访问将会直接在数据仓库目录中完成。 删除表时,表中的数据和元数据将会被同时删除 | 外部表 只有一个过程,加载数据和创建表同时完成,并不会移动到数据仓库目录中,只是与外部数据建立一个链接。当删除一个外部表时,仅删除该链接 |
内部表:
CREATE TABLE [IF NOT EXISTS] worker1
(
id INT,
name STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘,‘ --列分隔符
LINES TERMINATED BY ‘\n‘ --行分隔符
STORED AS ORC --存储格式,支持TextFile、Parquet、RCFile和ORC File
LOCATION ‘/user/hive/test/worker1‘--数据存放路径
外部表:
CREATE EXTERNAL TABLE [IF NOT EXISTS] worker2
(
id INT,
name STRING
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘,‘ --列分隔符
LINES TERMINATED BY ‘\n‘ --行分隔符
STORED AS ORC --存储格式,支持TextFile、Parquet、RCFile和ORC File
LOCATION ‘/user/hive/test/worker2‘--数据存放路径
内部表与外部表相互转换
alter table worker1 set TBLPROPERTIES (‘EXTERNAL‘=‘TRUE‘); --内部表转外部表
alter table worker1 set TBLPROPERTIES (‘EXTERNAL‘=‘FALSE‘); --外部表转内部表
动态创建表
动态创建表通常会用在创建临时表,又不想使用缓存(当然,hive不支持缓存,SparkSQL中支持)的情况
不修改字段名与类型:
CREATE TABLE worker_temp
STORED AS orc
AS
SELECT * FROM worker2
DROP TABLE [IF EXISTS] table_name
如果是外部表,并且有location,则需要通过hdfs删除对应的目录才能完全删除数据
TRUNCATE TABLE table_name;
ALTER TABLE employee RENAME TO emp;
hive> ALTER TABLE worker1 RENAME TO worker;
OK
Time taken: 1.156 seconds
hive> show tables;
OK
worker
worker2
下表包含employee表的字段,它显示的字段要被更改(粗体)。
字段名 | 从数据类型转换 | 更改字段名称 | 转换为数据类型 |
---|---|---|---|
eid | int | eid | int |
name | String | ename | String |
salary | Float | salary | Double |
designation | String | designation | String |
下面查询重命名使用上述数据的列名和列数据类型:
修改字段名
ALTER TABLE employee CHANGE name ename String
如:
hive> ALTER TABLE worker1 CHANGE name ename String
OK
Time taken: 0.398 seconds
hive> desc worker1;
OK
id int
ename string
修改字段类型
ALTER TABLE employee CHANGE salary salary Double
如:
hive> ALTER TABLE worker1 CHANGE ename name varchar(20);
OK
Time taken: 0.472 seconds
hive> desc worker1;
OK
id int
name varchar(20)
ALTER TABLE employee ADD COLUMNS (
dept STRING COMMENT ‘Department name‘,--COMMENT增加注释
test String
)
如
hive> ALTER TABLE worker1 ADD COLUMNS (
> dept STRING
> );
OK
Time taken: 0.372 seconds
hive> desc worker1;
OK
id int
name varchar(20)
dept string
Time taken: 0.309 seconds, Fetched: 3 row(s)
这个功能通常和增加列的功能一起用。
因为Hive增加列只能在最后的一个Column后面增加,假如我想在中间插入一列怎么办呢?
可以使用
ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]
由于hive文件并没有修改,只是相当于修改了字段名字而已,数据并没有相应的移动。
因此,此方法适用于已建表,后续会重新刷新数据的情况;或者空表。
目前貌似移除了这个功能
ALTER TABLE worker1 DROP COLUMN test1
ALTER TABLE worker1 REPLACE COLUMNS (
id INT,
name String
);
上面这条sql执行失败,提示 SerDe may be incompatible
ALTER TABLE worker1 CHANGE COLUMN c c string AFTER a;
desc worker1
show create table worker1
desc formatted worker1
ALTER TABLE worker1 SET FILEFORMAT textFile
show functions
Hive不支持单句插入的语句,必须批量,所以不要指望能用insert into workers values (1,‘jack‘) 这样的语句插入数据。hive支持的插入数据的方式有两种:
先建立一个叫 worker.csv的文件,内容为
1,jack
2,terry
3,michael
使用LOAD DATA 导入到Hive的表中
LOAD DATA LOCAL INPATH ‘/home/root/workers.csv‘ INTO TABLE workers1;
LOAD DATA LOCAL INPATH
跟 LOAD DATA INPATH
的区别是一个是从你本地磁盘上找源文件,一个是从hdfs上找文件LOAD DATA LOCAL INPATH ‘/home/root/workers.csv‘ OVERWRITE INTO TABLE workers1
;
INSERT [OVERWRITE] INTO TABLE works2
select * from test
如果有分区(稍后我们会讲到)
INSERT INTO [OVERWRITE] TABLE table_name1 PARTITION(partition_name1 data, partition_name2 data, … )
SELECT select_statement FROM from_statement;
分区表是用来加速查询的,比如你的数据非常多,但是你的应用场景是基于这些数据做日报表,那你就可以根据日进行分区,当你要做2014-05-05的报表的时候只需要加载2014-05-05这一天的数据就行了。
DROP TABLE IF EXISTS employee;
CREATE EXTERNAL TABLE IF NOT EXISTS employee
(
id INT,
name STRING,
dept String,
year int
)
PARTITIONED BY(p_year int)--指定分区,可以包含多级分区
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ‘,‘ --列分隔符
LINES TERMINATED BY ‘\n‘ --行分隔符
STORED AS textFile --存储格式,支持TextFile、Parquet、RCFile和ORC File
LOCATION ‘/user/hive/test/employeedata‘--数据存放路径
SHOW PARTITIONS employee;
DESC FORMATTED table_name partition (month = ‘2015-01’ , day = ‘2015-01-25′)
INSERT INTO TABLE table_name PARTITION PARTITION(p_column = ...)
SELECT * FROM other_table_name;
INSERT OVERWRITE TABLE table_name PARTITION PARTITION(p_column = ...)
SELECT * FROM other_table_name;
ALTER TABLE table_name ADD [IF NOT EXISTS ] PARTITION(p_column = ...) LOCATION "/user/root/test"
如:
ALTER TABLE employee ADD IF NOT EXISTS PARTITION(p_year = 2012) LOCATION "/user/hive/test/employeedata/2012";
ALTER TABLE employee ADD IF NOT EXISTS PARTITION(p_year = 2013) LOCATION "/user/hive/test/employeedata/2013";
ALTER TABLE table_name PARTITION (p_date="2015-12-12") RENAME TO PARTITION (p_date="2015-12-13");
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec, PARTITION partition_spec,...;
在hive中可以直接使用分区进行查询和计算操作,由于加入了分区,使得hive处理数据时可以读取指定分区的内容,而不用遍历全表,因此极大的加快了查询速度
如:
select * from employee where p_year = 2013;
结果:
+--------------+----------------+----------------+----------------+------------------+--+
| employee.id | employee.name | employee.dept | employee.year | employee.p_year |
+--------------+----------------+----------------+----------------+------------------+--+
| 3 | kaleel | SC | 2013 | 2013 |
| 4 | Prasanth | SC | 2013 | 2013 |
+--------------+----------------+----------------+----------------+------------------+--+
桶表是根据某个字段的hash值,来将数据扔到不同的“桶”里面。外国人有个习惯,就是分类东西的时候摆几个桶,上面贴不同的标签,所以他们取名的时候把这种表形象的取名为桶表。桶表表专门用于采样分析
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
CREATE TABLE b_student(id INT, name STRING)
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(id) --按照哪个字段分桶
SORTED BY(name)
INTO 4 BUCKETS --分成几个桶
row format delimited
fields TERMINATED BY ‘,‘;
创建
Array:
create table login_array(
ip string,
uid array<bigint>
)
partitioned by (dt string)
row format delemited fields terminated by ‘,‘--列分隔符
collection items terminated by ‘|‘ --数组分隔符
stored as textfile;
使用
select ip uid[0] from login_array where dt=‘20130101‘;--使用数组下标访问
select ip,size(uid) from login_array where dt=‘20130101‘;--查看数组长度
select * from login_array where array_contains(uid,‘31050007‘);--查找数组
创建
Map:
create table map_test_raw(
ip string,
request Map<string,string>
)
row format delemited fields terminated by ‘,‘ --列分隔符
collection items terminated by ‘|‘ --Map集合分隔符
map keys terminated by ‘=‘ --Key与value分隔符
stored as textfile;
使用
select request[‘src‘] from map_test_raw;
根据用户的需求创建视图。可以将任何结果集数据保存为一个视图。视图在Hive的用法和SQL视图用法相同。它是一个标准的RDBMS概念。我们可以在视图上执行所有DML操作。
CREATE VIEW worker_view AS
SELECT * FROM worker2
WHERE id>2;
DROP VIEW worker_view
索引也不过是一个表上的一个特定列的指针。创建索引意味着创建一个表上的一个特定列的指针。
CREATE INDEX worker_index ON TABLE worker2(id)
AS ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler‘
WITH DEFERRED REBUILD
SHOW INDEX ON worker2;
DROP INDEX worker_index ON worker2;
除了视图以外,还可以使用数据缓存的方式来保存某一结果集,只不过视图是将结果集保存在hive中,使用的时候仍旧运行了一次查询。而缓存则是将数据保存在了内存中,通常适用于需要多次使用的数据查询;但是,cache table的语法只能在Spark SQl中使用
整表缓存
sql=CACHE TABLE cache_worker AS SELECT * FROM worker2
DataFrame=hiveCtx.cacheTable("worker2")
或
hiveCtx.sql("SELECT * FROM worker2").cache()[或.persist()]
缓存部分数据
sql=CACHE TABLE cache_worker AS SELECT * FROM worker2 where id>1
DataFrame=hiveCtx.sql("SELECT * FROM worker2 where id>1").cache()[或.persist()]
该条语句对应了
sql=DROP TABLE cache_worker
DataFrame=hiveCtx.uncacheTable(cache_worker)
或dataframe.unpersist()
参考链接Hive教程
标签:刷新 reduce load data 字段名 数据类型转换 store res 数据集 ...
原文地址:http://www.cnblogs.com/kekukekro/p/6340980.html