创建表
hive> CREATE TABLE pokes (foo INT, bar STRING);
创建表并创建索引字段ds
hive> CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING);
显示所有表
hive> SHOW TABLES;
按正条件(正则表达式)显示表,
hive> SHOW TABLES '.*s';
表添加一列
hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);
添加一列并增加列字段注释
hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');
更改表名
hive> ALTER TABLE events RENAME TO 3koobecaf;
删除列
hive> DROP TABLE pokes;
元数据存储
将文件中的数据加载到表中
hive> LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE pokes;
加载本地数据,同时给定分区信息
hive> LOAD DATA LOCAL INPATH './examples/files/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
加载DFS数据 ,同时给定分区信息
hive> LOAD DATA INPATH '/user/myname/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
The above command will load data from an HDFS file/directory to the table. Note that loading data from HDFS will result in moving the file/directory. As a result, the operation is almost instantaneous.
SQL 操作
按先件查询
hive> SELECT a.foo FROM invites a WHERE a.ds='<DATE>';
将查询数据输出至目录
hive> INSERT OVERWRITE DIRECTORY '/tmp/hdfs_out' SELECT a.* FROM invites a WHERE a.ds='<DATE>';
将查询结果输出至本地目录
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/local_out' SELECT a.* FROM pokes a;
选择所有列到本地目录
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/reg_3' SELECT a.* FROM events a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_4' select a.invites, a.pokes FROM profiles a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT COUNT(1) FROM invites a WHERE a.ds='<DATE>';
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT a.foo, a.bar FROM invites a;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/sum' SELECT SUM(a.pc) FROM pc1 a;
将一个表的统计结果插入另一个表中
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar, count(1) WHERE a.foo > 0 GROUP BY a.bar;
hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(1) FROM invites a WHERE a.foo > 0 GROUP BY a.bar;
JOIN
hive> FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;
将多表数据插入到同一表中
FROM src
INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100
INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200
INSERT OVERWRITE TABLE dest3 PARTITION(ds='2008-04-08', hr='12') SELECT src.key WHERE src.key >= 200 and src.key < 300
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dest4.out' SELECT src.value WHERE src.key >= 300;
将文件流直接插入文件
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09';
This streams the data in the map phase through the script /bin/cat (like hadoop streaming). Similarly - streaming can be used on the reduce side (please see the Hive Tutorial or examples)
实际示例
创建一个表
CREATE TABLE u_data (
userid INT,
movieid INT,
rating INT,
unixtime STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;
下载示例数据文件,并解压缩
wget http://www.grouplens.org/system/files/ml-data.tar__0.gz
tar xvzf ml-data.tar__0.gz
加载数据到表中
LOAD DATA LOCAL INPATH 'ml-data/u.data'
OVERWRITE INTO TABLE u_data;
统计数据总量
SELECT COUNT(1) FROM u_data;
现在做一些复杂的数据分析
创建一个 weekday_mapper.py: 文件,作为数据按周进行分割
import sys
import datetime
for line in sys.stdin:
line = line.strip()
userid, movieid, rating, unixtime = line.split('\t')
生成数据的周信息
weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print '\t'.join([userid, movieid, rating, str(weekday)])
使用映射脚本
//创建表,按分割符分割行中的字段值
CREATE TABLE u_data_new (
userid INT,
movieid INT,
rating INT,
weekday INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';
//将python文件加载到系统
add FILE weekday_mapper.py;
将数据按周进行分割
INSERT OVERWRITE TABLE u_data_new
SELECT
TRANSFORM (userid, movieid, rating, unixtime)
USING 'python weekday_mapper.py'
AS (userid, movieid, rating, weekday)
FROM u_data;
SELECT weekday, COUNT(1)
FROM u_data_new
GROUP BY weekday;
————————————————————————————————————————————————————
hive update delete:
关于 hive 的更新和删除问题,csdn 曾举办过活动来专门讨论过,
http://10773851.42qu.com/10773869
总结如下:
HIVE是一个数据仓库系统,这就意味着它可以不支持普通数据库的CRUD操作。CRUD应该在导入HIVE数据仓库前完成。
而且鉴于 hdfs 的特点,其并不能高效的支持流式访问,访问都是以遍历整个文件块的方式。hive 0.7 之后已经支持
索引,但是很弱,尚没有成熟的线上方案。
关于 hive 的删除和更新有如下办法:
一、行级的更新和删除:通过 hbase 进行。
数据保存在HBase中,Hive从HBase中查询数据,这个官方提供 hive-hbase-handler 插件支持,通过 thrift hive-service 进行通信
优点:
适用性比较普遍,单行和批量修改都可以使用,并且修改也比较方便;修改也比较快速。
缺点:
(1)查询的时候,性能较数据保存在HDFS的场景慢一些。
(2)通过 hbase 删除可能会有延时导致脏数据,因为 habse 删数据是先逻辑删除,然后等待下一次 compact 再物理删除。
(3)这种方式产生的 hive 表将不能再更改表结构,alt table 操作直接抛异常。
(4)尚没有验证这种方案在大数据量的场景下的可行性。
二、批量更新和删除:可以相应的使用 insert as select 的方式来实现。
不更改HIVE的设计,利用HiveQL实现update和delete,虽然效率比较低,但是也可以实现update和delete操作。
delete操作实现:
用select语句筛选出不delete的数据,用这些数据覆盖原来的表,如我们想删除score在60分以下的行,可以用:
INSERT OVERWRITE students SELECT students.* from students where score >= 60;
update操作的实现:
将要更新的数据从数据库中选出放入一个本地临时的文件中,如要更新60分以下的学生的数据,可以使用:
INSERT OVERRITE LOCAL DIRECTORY "/tmp/students.1" SELECT students.* from students where score < 60;
删除要更新的数据:
INSERT OVERWRITE students SELECT students.* from students where score >=60;
编辑要更新的数据文件或者将要修改的数据放入数据库表后再修改,修改结束后载入到表中:LOAD DATA INPATH "/tmp/students.1" INTO TABLE students如果对表进行分区,上述的update和delete速度会快一些。
缺点:
同一个操作扫描了 2 遍 hdfs,还不如 MR 批量更新来得快和简洁。