解决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和关系型数据库之间进行数据的导入导出,其中主要使用了import
和export
这两个工具。这两个工具非常强大,提供了很多选项帮助我们完成数据的迁移和同步。比如,下面两个潜在的需求:业务数据存放在关系数据库中,如果数据量达到一定规模后需要对其进行分析或同统计,单纯使用关系数据库可能会成为瓶颈,这时可以将数据从业务数据库数据导入(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 | 从表中导出指定的一组列的数据 |
–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 | 合并键,一般是主键ID |
–jar-file | 合并时引入的jar包,该jar包是通过Codegen工具生成的jar包 |
–class-name | 对应的表名或对象名,该class类是包含在jar包中的。 |
–target-dir | 合并后的数据在HDFS里的存放目录 |