hive学习练习&Sqoop知识补充

解决SecureCRT 进入hive模式后无法删除数据的问题,打开会话设置,终端模拟,选择Linux即可

Databases in Hive

如果在hive中未定义数据库的话,这个“default”作为默认的数据库。

创建数据库

语法

create database userdb;

如果userdb存在的话,就会抛出错误,可以这样:

create database IF NOT EXISTS userdb;

在“database”相关命令行可以使用“schema”代替“database”。
如果存在较多的数据库,可以使用相关的表达式,like或alike+数据库名开头的字母和以”.*”结尾,如:

hive> show databases like ‘u.*’;   (f代表userdb数据库)

hive为每个数据库创建一个路径,每个表对应一个文件夹,表被存储在相应的子路径中。默认的“default”的数据库没有自己的路径;数据库的路径这个属性中设置:hive.metastore.warehouse.dir,其中默认的属性值是/user/hive/warehouse
当数据库userdb被创建,hive会为其创建路径为/user/hive/warehouse/userdb.db,.db是数据库名的扩展。
你也可以修改默认的路径:

create database userdb
location ‘/my/preferred/directory’;

可以为数据库增加解释性内容:

create database userdb
comment ‘holds all about user tables’;

以下命令,显示数据库的路径。

describe database userdb;

将key-values属性和数据库结合起来,如:

create database userdb
with dbproperties (‘creator=’leon’,’data’=’2016-08-19’);

“use”命令是让某一数据库处于“当前使用的数据库”状态:

use userdb;

可惜没用命令可以表现出当前正在使用的数据库,因此我们使用’use’命令设置数据库为当前使用的数据库。因为在hive中没有数据库的概念。
删除数据库

drop database if exists userdb;

默认情况下,hive是不允许删除含有表的数据库,首先删除表,之后在命令行使用‘CASCADE’关键词,同样可以使用‘RESTRICT’:

drop database if exists userdb cascade;

当数据库被删除,其路径也被删除了。
在‘DBPROPERTIES’中可以设置键值对属性。

alter database userdb set dbproperties(‘edited-by’=’leon’);

基本操作

  • 建表
create table t_order (order_sn string, user_id string,amount int,create_time timestamp)
row format delimited fields terminated by '\t';

创建一个表作为外部表(指定location 参数会创建相应的目录,如果未指定该参数,则会在默认位置(/user/hive/warehouse/userdb.db/t_order_in_ex)创建一个目录)
带location参数外部表:

create external table t_order_ex (order_sn string, user_id string,amount int,create_time timestamp)
row format delimited fields terminated by '\t'
location '/external/hive/t_order_ex';

不带location参数外部表:

create external table t_order_in_ex (order_sn string, user_id string,amount int,create_time timestamp)
row format delimited fields terminated by '\t';

分别向order,t_order_ex,t_order_in_ex 表中load本地数据hivetb.txt

load data local inpath '/root/hivetb.txt' into table t_order;
load data local inpath '/root/hivetb.txt' into table t_order_ex;
load data local inpath '/root/hivetb.txt' into table t_order_in_ex;

查询加载的数据

select * from t_order;
select * from t_order_ex;
select * from t_order_in_ex;

三个表中的数据是完全一样的。

select count(*) from t_order_wk;

打开hdfs的web界面,查看hdfs中hive数据库文件夹和表文件夹中的数据,在三个表对应的hdfs目录下都会有一个hivetb.txt文件
手动向hdfs中t_order_ex文件夹中上传某个文件,文件中部分数据格式与表设置的格式不一致
如:(第三行只有三列缺第四列,第四行只有三列缺第三列,第五行的第三列不是要求的int类型)

3016080910 30086 10 2016-08-19 11:50:50
3016080911 30086 11 2016-08-19 11:51:22
3016080912 30000 9
3016080913 30000 2016-08-19 11:52:12
3016080914 30010 5rmb 2016-08-19 11:53:59

上传到外部表前验证数据:

2016080910 10086 10 2016-08-19 11:50:50
2016080911 10086 11 2016-08-19 11:51:22
2016080912 10000 9 2016-08-19 11:51:42
2016080913 10000 20 2016-08-19 11:52:12
2016080914 10010 100 2016-08-19 11:53:59

hdfs dfs -put /root/hiveatb.txt /external/hive/t_order_ex

查询验证(可以查询出相关信息,少的最后补NULL,多的忽略,格式不符的以NULL代替)

select * from t_order_ex;

2016080910 10086 10 2016-08-19 11:50:50
2016080911 10086 11 2016-08-19 11:51:22
2016080912 10000 9 2016-08-19 11:51:42
2016080913 10000 20 2016-08-19 11:52:12
2016080914 10010 100 2016-08-19 11:53:59
3016080910 30086 10 2016-08-19 11:50:50
3016080911 30086 11 2016-08-19 11:51:22
3016080912 30000 9 NULL
3016080913 30000 NULL NULL
3016080914 30010 NULL 2016-08-19 11:53:59

将数据上传到内部表t_order,并查看上传后的数据。

hdfs dfs -put /root/hiveatb.txt /user/hive/warehouse/userdb.db/t_order

同样可以直接查询到新增加的数据。
由以上可知,将数据文件移动/复制到对应的hdfs文件夹下后,就可以使用hive查询到数据了。

如果数据文件原本就在hdfs上,当我们加载hdfs上的数据到创建的(内部)表的时候,直接将文件移动到该hdfs文件夹下

load data inpath '/hiveatb.txt' into table t_order_in_ex;

加载后,文件被移动到了对应表的hdfs文件夹下,同样可以直接查询到新增加的数据。
external类型的表,表对应的是文件夹,对于文件的位置不做任何限制,放到任何hdfs上到底位置都可以。

  • 删除表操作
drop table t_order;
drop table t_order_ex;
drop table t_order_in_ex;

drop内部表时,会删除hdfs上的文件夹和元数据
drop external表时,不会对外部文件数据做任何操作(t_order_ex和t_order_in_ex文件夹均还在)

重新执行创建表的操作,恢复hive数据库到未删除前,继续进行下面的练习,外部表的数据因为没有删除所有数据直接可查,内部表数据需要重新加载。

  • 创建表的另外一种方式
show tables;

OK
t_order
t_order_ex
t_order_in_ex

  • 创建表时通过SQL语句得到表结构和数据,用于创建一些临时表存储中间结果,这样的表在hdfs中有相应的目录结构和文件
create table t_order_order_sn
as
select order_sn,user_id from t_order;

显示所有表

show tables;

OK
t_order
t_order_ex
t_order_in_ex
t_order_order_sn

创建成功。查看所创建t_order_order_sn表的表结构。

desc t_order_order_sn;

OK
order_sn string
user_id string

  • 复制表结构(只能复制表结构,无法复制表的内容)
create table t_order_like like t_order;

查看表

show tables;

OK
t_order
t_order_ex
t_order_in_ex
t_order_like
t_order_order_sn

  • insert into 是追加数据,overwrite是覆盖写所有表
insert overwrite table t_order_like
    select * from t_order;
  • 分区表
    PARTITION(分区)添加一个新字段作为分区字段,在hdfs中表现为在t_order_part文件夹下创建以分区命名的文件夹,只能在创建表的时候就指定好(partitioned关键字必须在row format 之前)
create table t_order_part (order_sn string, user_id string,amount int,create_time timestamp)
partitioned by (month string)
row format delimited fields terminated by '\t';

如果是多个字段”分区组“,则将partitioned by (month string)替换为partitioned by (pname1 ptype1,pname2 ptype2 ...)

查看分区表结构

desc t_order_part;

OK
order_sn string
user_id string
amount int
create_time timestamp
month string
# Partition Information
# col_name data_type comment
month string

加载数据到分区表

• 加载的目标可以是一个表或者分区。如果表包含分区,必须指定每一个分区的分区名
• filepath 可以引用一个文件(这种情况下,Hive 会将文件移动到表所对应的目录中)或者是一个目录(在这种情况下,Hive 会将目录中的所有文件移动至表所对应的目录中)

• LOCAL关键字,即本地
• load 命令会去查找本地文件系统中的 filepath。如果发现是相对路径,则路径会被解释为相对于当前用户的当前路径。用户也可以为本地文件指定一个完整的 URI,比如:file:///user/hive/project/data1.
• load 命令会将 filepath 中的文件复制到目标文件系统中。目标文件系统由表的位置属性决定。被复制的数据文件移动到表的数据对应的位置

例如:加载本地数据,同时给定分区信息:

load data local inpath '/root/hivetb.txt' into table t_order_part partition (month='20160820');

overwrite会覆盖写对应分区下的数据,不写该参数就是追加

load data local inpath '/root/hivetb.txt' overwrite into table t_order_part partition (month='20160821');

查看数据

select * from t_order_part;

2016080910 10086 10 2016-08-19 11:50:50 20160820
2016080911 10086 11 2016-08-19 11:51:22 20160820
2016080912 10000 9 2016-08-19 11:51:42 20160820
2016080913 10000 20 2016-08-19 11:52:12 20160820
2016080914 10010 100 2016-08-19 11:53:59 20160820
2016080910 10086 10 2016-08-19 11:50:50 20160821
2016080911 10086 11 2016-08-19 11:51:22 20160821
2016080912 10000 9 2016-08-19 11:51:42 20160821
2016080913 10000 20 2016-08-19 11:52:12 20160821
2016080914 10010 100 2016-08-19 11:53:59 20160821

根据分区字段查询,只会显示对应分区的结果

select * from t_order_part  where month='20160820';
select count(*) from t_order_part where month='20160820';

增加分区必须在创建表的时候就指定了分区列才可以,后期不能增加分区列,只能增加分区字段的值。

ALTER TABLE t_order_part ADD PARTITION (month = '20160822') location '/external/20160822';

如果/external/20160822 目录不存在,hdfs会创建该目录。

show partitions t_order_part;

OK
month=20160820
month=20160821
month=20160822

此时该分区没有值
/external/20160822目录中上传数据

hdfs dfs -put /root/hiveatb.txt /external/20160822

查看数据

select * from t_order_part;

OK
2016080910 10086 10 2016-08-19 11:50:50 20160820
2016080911 10086 11 2016-08-19 11:51:22 20160820
2016080912 10000 9 2016-08-19 11:51:42 20160820
2016080913 10000 20 2016-08-19 11:52:12 20160820
2016080914 10010 100 2016-08-19 11:53:59 20160820
2016080910 10086 10 2016-08-19 11:50:50 20160821
2016080911 10086 11 2016-08-19 11:51:22 20160821
2016080912 10000 9 2016-08-19 11:51:42 20160821
2016080913 10000 20 2016-08-19 11:52:12 20160821
2016080914 10010 100 2016-08-19 11:53:59 20160821
3016080910 30086 10 2016-08-19 11:50:50 20160822
3016080911 30086 11 2016-08-19 11:51:22 20160822
3016080912 30000 9 NULL 20160822
3016080913 30000 NULL NULL 20160822
3016080914 30010 NULL 2016-08-19 11:53:59 20160822

创建hdfs目录

hdfs dfs -mkdir /external/datapart

将本地数据通过hdfs上传到该目录中

hdfs dfs -put /root/hiveatb.txt /external/datapart/

通过ADD添加新分区,并将指定/external/datapart为数据目录

alter table t_order_part add partition (month='20160824') location '/external/datapart';

hive命令的3种调用方式

方式1:交互模式下,hive –f /root/shell/hive-script.sql(适合多语句)

Hive可以运行保存在文件里面的一条或多条的语句,只要用-f参数,一般情况下,保存这些Hive查询语句的文件通常用.q或者.hql后缀名,但是这不是必须的,你也可以保存你想要的后缀名。hive-script.sql类似于script一样,直接写查询命令就行。
例如,编辑并填入如下内容:

vi hive_script3.sql

select * from t1;
select count(*) from t1;

不进入交互模式,执行一个hive script

这里可以和静音模式-S(不会显示mapreduct的操作过程)联合使用,通过第三方程序调用,第三方程序通过hive的标准输出获取结果集。

[root@hadoopcswfb iwisdom]# /iwisdom/hive-1.4.4/bin/hive -S -f /hive-script.sql
  • 那么问题来了:如何传递参数呢?

demo如下:

start_hql.sh 内容:

#!/bin/bash
# -S 打印输出mapreduce日志
hive \
  -hivevar col1=2016080910 \
  -hivevar col2=10086 \
  -S -f test.sql

test.sql 内容:
我使用userdb数据库中的t_order表作演示查询

use userdb;
select * from t_order where id='${hivevar:col1}' and col2='${hivevar:col2}';

为start_hql.sh添加执行权限

chmod +x start_hql.sh
./start_hql.sh
方式2:非交互模式下,hive -e ‘sql语句’(适合短语句)

直接执行sql语句
如果设置环境变量$PATH=$HIVE_HOME\bin 即可直接使用hive命令
例如:

[root@hadoopcswfb iwisdom]# hive -e 'use userdb';
[root@hadoopcswfb iwisdom]# hive -e 'select * from t_order';

静音模式:(用法与第一种方式的静音模式一样,不会显示mapreduce的操作过程)

[root@hadoopcswfb iwisdom]# hive -S -e 'select * from t_order';

此处还有一亮点,用于导出数据到linux本地目录下
例如:

[root@hadoopcswfb iwisdom]# hive -e 'select * from t_order'  > test.txt
方式3:hive (直接使用hive交互式模式)

Sqoop拾遗&利用sqoop实现MySQL与Hive互导数据

Sqoop可以在HDFS/Hive和关系型数据库之间进行数据的导入导出,其中主要使用了importexport这两个工具。这两个工具非常强大,提供了很多选项帮助我们完成数据的迁移和同步。比如,下面两个潜在的需求:业务数据存放在关系数据库中,如果数据量达到一定规模后需要对其进行分析或同统计,单纯使用关系数据库可能会成为瓶颈,这时可以将数据从业务数据库数据导入(import)到Hadoop平台进行离线分析。对大规模的数据在Hadoop平台上进行分析以后,可能需要将结果同步到关系数据库中作为业务的辅助数据,这时候需要将Hadoop平台分析后的数据导出(export)到关系数据库。
这里,我们介绍Sqoop完成上述基本应用场景所使用的import和export工具,通过一些简单的例子来说明这两个工具是如何做到的。
工具通用选项
import和export工具有些通用的选项,如下表所示:

选项 含义说明
–connect 指定JDBC连接字符串
–connection-manager 指定要使用的连接管理器类
–driver 指定要使用的JDBC驱动类
–hadoop-mapred-home 指定$HADOOP_MAPRED_HOME路径
–help 打印用法帮助信息
–password-file 设置用于存放认证的密码信息文件的路径
-P 从控制台读取输入的密码
–password 设置认证密码
–username 设置认证用户名
–verbose 打印详细的运行信息
–connection-param-file 可选,指定存储数据库连接参数的属性文件

数据导入工具import

import工具,是将HDFS平台外部的结构化存储系统中的数据导入到Hadoop平台,便于后续分析。我们先看一下import工具的基本选项及其含义,如下表所示:

选项 含义说明
–append 将数据追加到HDFS上一个已存在的数据集上
–as-avrodatafile 将数据导入到Avro数据文件
–as-sequencefile 将数据导入到SequenceFile
–as-textfile 将数据导入到普通文本文件(默认)
–boundary-query 边界查询,用于创建分片(InputSplit)
–columns <col,col,col…> 从表中导出指定的一组列的数据
–delete-target-dir 如果指定目录存在,则先删除掉
–direct 使用直接导入模式(优化导入速度)
–direct-split-size 分割输入stream的字节大小(在直接导入模式下)
–fetch-size 从数据库中批量读取记录数
–inline-lob-limit 设置内联的LOB对象的大小
-m,–num-mappers 使用n个map任务并行导入数据
-e,–query 导入的查询语句
–split-by 指定按照哪个列去分割数据
–table 导入的源表表名
–target-dir 导入HDFS的目标路径
–warehouse-dir HDFS存放表的根路径
–where 指定导出时所使用的查询条件
-z,–compress 启用压缩
–compression-codec 指定Hadoop的codec方式(默认gzip)
–null-string 果指定列为字符串类型,使用指定字符串替换值为null的该类列的值
–null-non-string 如果指定列为非字符串类型,使用指定字符串替换值为null的该类列的值

下面,我们通过实例来说明,在实际中如何使用这些选项。
和Hive相关的参数

参数 说明
–hive-home Hive的安装目录,可以通过该参数覆盖掉默认的hive目录
–hive-overwrite 覆盖掉在hive表中已经存在的数据
–create-hive-table 默认是false,如果目标表已经存在了,那么创建任务会失败
–hive-table 后面接要创建的hive表
–table 指定关系数据库表名
  • 将MySQL数据库中整个表数据导入到Hive表
sqoop import --connect jdbc:mysql://192.168.0.100/userdb --username root --password 123 --table t_order --hive-import -- --default-character-set=utf-8;

将MySQL数据库userdb中t_order表的数据导入到Hive表中。

  • 将MySQL数据库中多表JION后的数据导入到HDFS
sqoop import \
--connect jdbc:mysql://192.168.0.100:3306/userdb \
--username root \
--password 123 \
--query 'select f_order.*,userinfo.username from f_order join userinfo on (f_order.user_id=userinfo.user_id) where $CONDITIONS' \
--hive-import \
--hive-database userdb \
--create-hive-table \
--hive-table f_order_userinfo \
--target-dir /myinfo/f_order_userinfo \
--split-by f_order.user_id

这里,使用了--query选项,不能同时与--table选项使用。而且,变量$CONDITIONS必须在WHERE语句之后,供Sqoop进程运行命令过程中使用。上面的--target-dir指向的其实就是Hive表存储的数据目录,此字段必须指定。

  • 创建Sqoop Job,将MySQL数据库中某个表的数据增量同步到Hive表

增量实现的原始思路
要想实现增量导入,完全可以不使用Sqoop的原生增量特性,仅使用shell脚本生成一个以当前时间为基准的固定时间范围,然后拼接Sqoop命令语句即可。
原生增量导入特性简介
Sqoop提供了原生增量导入的特性,包含以下三个关键参数:

Argument Description
–check-column (col) 指定一个“标志列”用于判断增量导入的数据范围,该列不能是字符型,最好是数字或者日期型(这个很好理解吧)。
–incremental (mode) 指定增量模式,包含“追加模式” append(关于append的介绍请参见另一篇文章) 和“最后修改模式” lastmodified (该模式更满足常见需求)。
–last-value (value) 指定“标志列”上次导入的上界。如果“标志列”是最后修改时间,则–last-value为上次执行导入脚本的时间。

结合Saved Jobs机制,可以实现重复调度增量更新Job时 –last-value 字段的自动更新赋值,再结合cron或者oozie的定时调度,可实现真正意义的增量更新。

sqoop job \
--create myjob \
-- import \
--connect jdbc:mysql://192.168.0.100:3306/userdb \
--table t_order \
--username root \
--password 123 \
--hive-import \
--hive-database userdb \
--hive-table f_order_userinfo \
--incremental lastmodified \
--check-column create_time \
--last-value '2016-08-18 11:58:36'  --append

注意1:第三行的-- import之间必须有一个空格。
注意2:最后一行last-value的值除了指定一个时间外,还需要添加–append或–merge-key否则在第二次执行的时候会提示表目录已经存在。

首先查看一下该Job 的incremental.last.value,注意和下面第二次做对比。

[root@hadoopcswfb iwisdom]# sqoop job --show myjob;

注意观察以下结果:

Warning: /usr/lib/hbase does not exist! HBase imports will fail.
Please set $HBASE_HOME to the root of your HBase installation.
Warning: /usr/lib/hcatalog does not exist! HCatalog jobs will fail.
Please set $HCAT_HOME to the root of your HCatalog installation.
Enter password:
Job: myjob
Tool: import
Options:
----------------------------
verbose = false
**incremental.last.value = 2016-08-18 11:58:36**
db.connect.string = jdbc:mysql://192.168.0.100:3306/userdb
codegen.output.delimiters.escape = 0
codegen.output.delimiters.enclose.required = false
codegen.input.delimiters.field = 0
hbase.create.table = false
db.require.password = true
hdfs.append.dir = false
db.table = t_order
import.fetch.size = null
codegen.input.delimiters.escape = 0
codegen.input.delimiters.enclose.required = false
db.username = root
codegen.output.delimiters.record = 10
import.max.inline.lob.size = 16777216
hcatalog.create.table = false
db.clear.staging.table = false
incremental.col = create_time
codegen.input.delimiters.record = 0
enable.compression = false
hive.overwrite.table = false
hive.import = true
codegen.input.delimiters.enclose = 0
hive.table.name = t_order
hive.database.name = userdb
hive.drop.delims = false
codegen.output.delimiters.enclose = 0
hdfs.delete-target.dir = false
codegen.output.dir = .
codegen.auto.compile.dir = true
mapreduce.num.mappers = 4
import.direct.split.size = 0
codegen.output.delimiters.field = 1
export.new.update = UpdateOnly
incremental.mode = DateLastModified
hdfs.file.format = TextFile
codegen.compile.dir = /tmp/sqoop-root/compile/cac84cfd83e2a71d659a57e00fe08a06
direct.import = false
hive.fail.table.exists = false
db.batch = false

执行前查看一下mySQL数据库userdb的t_order表的数据,这里只截取最新的一条.

2016080929 10010 100 2016-08-18 11:58:36

查看hive中的userdb数据库t_order表的最新一条数据:

2016080929 10010 100 2016-08-18 11:58:36.0

第一次执行 Job

[root@hadoopcswfb iwisdom]# sqoop job --exec myjob

执行后
我们向MySQL中的t_order表添加一条数据,如下所示(时间自动生成,我这里指定一个):

2016080930 10011 200 2016-08-20 01:51:30

查看执行后,hive上的t_order数据是否有变化,结果是:与执行job前一样,数据没有增加

我们再次查看Job的详细信息。

[root@hadoopcswfb iwisdom]# sqoop job --show myjob;

结果如下:

    Warning: /usr/lib/hbase does not exist! HBase imports will fail.
    Please set $HBASE_HOME to the root of your HBase installation.
    Warning: /usr/lib/hcatalog does not exist! HCatalog jobs will fail.
    Please set $HCAT_HOME to the root of your HCatalog installation.
    Enter password: 
    Job: myjob
    Tool: import
    Options:
    ----------------------------
    verbose = false
    **incremental.last.value = 2016-08-20 01:48:34.0**
    db.connect.string = jdbc:mysql://192.168.0.100:3306/userdb
    codegen.output.delimiters.escape = 0
    codegen.output.delimiters.enclose.required = false
    codegen.input.delimiters.field = 0
    hbase.create.table = false
    db.require.password = true
    hdfs.append.dir = false
    db.table = t_order
    import.fetch.size = null
    codegen.input.delimiters.escape = 0
    codegen.input.delimiters.enclose.required = false
    db.username = root
    codegen.output.delimiters.record = 10
    import.max.inline.lob.size = 16777216
    hcatalog.create.table = false
    db.clear.staging.table = false
    incremental.col = create_time
    codegen.input.delimiters.record = 0
    enable.compression = false
    hive.overwrite.table = false
    hive.import = true
    codegen.input.delimiters.enclose = 0
    hive.table.name = t_order
    hive.database.name = userdb
    hive.drop.delims = false
    codegen.output.delimiters.enclose = 0
    hdfs.delete-target.dir = false
    codegen.output.dir = .
    codegen.auto.compile.dir = true
    mapreduce.num.mappers = 4
    import.direct.split.size = 0
    codegen.output.delimiters.field = 1
    export.new.update = UpdateOnly
    incremental.mode = DateLastModified
    hdfs.file.format = TextFile
    codegen.compile.dir = /tmp/sqoop-root/compile/64827b1118b076a00a8d0a47a94a3d05
    direct.import = false
    hive.fail.table.exists = false
    db.batch = false

我们发现incremental.last.value = 2016-08-20 01:48:34.0的值被更新到执行时候的时间了。
我们再次执行该job,因为我在数据插入了一条数据,该数据的时间在上面这个值之后,也就是比他新。我们观察执行后,hive上t_order表数据的变化。

第二次执行 Job

[root@hadoopcswfb iwisdom]# sqoop job --exec myjob

执行后,查询新myjob信息,只列出incremental.last.value如下,该值为第二次执行myjob的时间:

incremental.last.value = 2016-08-20 02:22:57.0
查询hive上的t_order表数据的变化,同样我只列出最新的两条,如下所示:

2016080929 10010 100 2016-08-18 11:58:36.0
2016080930 10011 200 2016-08-20 01:51:30.0

LASTMODIFIED的下界是上一次执行该job的上界,也就是说,Sqoop的“Saved Jobs”机制对于增量导入类Job,自动记录了上一次的执行时间,并自动将该时间赋值给下一次执行的–last-value参数!也就是说,我们只需要通过crontab设定定期执行该job即可,job中的–last-value将被“Saved Jobs”机制自动更新以实现真正意义的增量导入。

  • 将MySQL数据库中某个表的几个字段的数据导入到Hive表
sqoop import \
--connect jdbc:mysql://192.168.0.100:3306/userdb \
--username root \
--password 123 \
--table t_order \
--columns 'order_sn,user_id' \
--hive-import \
--hive-database userdb \
--create-hive-table \
-target-dir /user/hive/warehouse/userdb.db/t_order_sn_uid \
-m 1 \
--hive-table t_order_sn_uid

我们这里将MySQL数据库userdb中t_order表的order_sn和user_id字段的值导入到Hive表t_order_sn_uid。其中--create-hive-table选项会自动创建Hive表,--hive-import选项会将选择的指定列的数据导入到Hive表。如果在Hive中通过SHOW TABLES无法看到导入的表,可以在conf/hive-site.xml中显式修改如下配置选项:

<property>
     <name>javax.jdo.option.ConnectionURL</name>
     <value>jdbc:derby:;databaseName=hive_metastore_db;create=true</value>
</property>

然后再重新运行,就能看到了。

数据导出工具export

export工具,是将HDFS平台的数据,导出到外部的结构化存储系统中,可能会为一些应用系统提供数据支持。我们看一下export工具的基本选项及其含义,如下表所示:

选项 含义说明
–validate 启用数据副本验证功能,仅支持单表拷贝,可以指定验证使用的实现类
–validation-threshold 指定验证门限所使用的类
–direct 使用直接导出模式(优化速度)
–export-dir 导出过程中HDFS源路径
-m,–num-mappers 使用n个map任务并行导出
–table 导出的目的表名称
–call 导出数据调用的指定存储过程名
–update-key 更新参考的列名称,多个列名使用逗号分隔
–update-mode 指定更新策略,包括:updateonly(默认)、allowinsert
–input-null-string 使用指定字符串,替换字符串类型值为null的列
–input-null-non-string 使用指定字符串,替换非字符串类型值为null的列
–staging-table 在数据导出到数据库之前,数据临时存放的表名称
–clear-staging-table 清除工作区中临时存放的数据
–batch 使用批量模式导出
其他1 空值的处理

默认情况下,如果RDB中存在空值,则导入时用字符串常量null(小写)代替所有空值。此种处理方式并不符合大多数的空值处理要求。而Sqoop提供了2个参数以供处理空值:
其中null-string用于处理数据库中文本类型的字段,null-non-string用于处理非文本类型的字段

sqoop import --connect jdbc:oracle:thin:@//myoracle:1521/pdbORCL --username DM --password-file sqoop.pwd --table PUB_DATE_D --where "QUARTER_NAME<'Q2'" --hive-import --hive-database default --null-string '\\N' --null-non-string '\\N'

其他2 合并 hdfs 文件

将HDFS中不同目录下面的数据合在一起,并存放在指定的目录中,示例如:

sqoop merge –new-data /test/p1/person –onto /test/p2/person –target-dir /test/merged –jar-file /opt/data/sqoop/person/Person.jar –class-name Person –merge-key id

其中,–class-name 所指定的 class 名是对应于 Person.jar 中的 Person 类,而 Person.jar 是通过 Codegen 生成的

参数 说明
–new-data Hdfs中存放数据的一个目录,该目录中的数据是希望在合并后能优先保留的,原则上一般是存放越新数据的目录就对应这个参数。
–onto Hdfs中存放数据的一个目录,该目录中的数据是希望在合并后能被更新数据替换掉的,原则上一般是存放越旧数据的目录就对应这个参数。
–merge-key <col> 合并键,一般是主键ID
–jar-file 合并时引入的jar包,该jar包是通过Codegen工具生成的jar包
–class-name 对应的表名或对象名,该class类是包含在jar包中的。
–target-dir 合并后的数据在HDFS里的存放目录

参考文献1
参考文献2

  • 浏览:2068
  • 评论:0

发表新的回复