Hive学习笔记(2)

Hive学习笔记

笔记内容主要来自Hive编程指南

HiveQL:数据定义

Hive中的数据库

Hive中数据库的概念本质上仅仅是表的一个目录或者命名空间。

如果用户没有显示指定数据库,那么将会使用默认的数据库default

CREATE DATABASE financials; --创建数据库
CREATE DATABASE IF NOT EXISTS financials; --判断是否存在同名库
SHOW DATABASES;--显示所有数据库
SHOW DATABASE LIKE 'h.*';--模糊查询所有匹配数据库
CREATE DATABASE financials LOCATION 'my/mypath';--用户可以通过命令来修改数据库默认位置
CREATE DATEBASE financials COMMENT 'jinesse create';--添加描述信息
DESCRIBE DATABASE financials;--显示详细描述信息
DESCRIBE DATABASE EXTENDED financials;--显示扩展详细描述信息
USE financials;--选择数据库
set hive.cli.print.current.db=true;--在cli当中显示当前数据库属性
DROP DATABASE IF EXISTS financials;--删除数据库
DROP DATABASE IF EXISTS financials CASCADE;--默认情况下(RESTRICT)是不允许用户删除一个包含有表的数据库,删除命令最后面加上关键字CASCADE,这样可以使Hive自行先删除数据库中的表

修改数据库

ALTER DATABASE financials SET DBPROPERTIES('EDITED-BY'='Joe Dba')--修改数据库描述属性信息。数据库的其他元数据信息都是不可以更改的,包括数据库名和数据库所在的目录位置。

创建表

基本操作

CREATE TABLE IF NOT EXISTS mydb.employees(
    name          STRING COMMENT 'Employee name',
    salary        FLOAT COMMENT 'Employee salary',
    subordinates  ARRAY<STRING> COMMENT 'Names of subordinates',
    deductions    MAP<STRING,FLOAT> COMMENT 'Keys are deductions name,values are percentages',
    address       STRUCT<street:STRING, city:STRING, zip:INT> COMMENT 'Home address')
COMMENT 'Description of the table'
TBLPROPERTIES ('creator'='me', 'created_at'='2012-01-02 10:00:00', ...)
LOCATION '/user/hive/...';
--可以为表指定目录
--用户可以拷贝一张已经存在的表的表模式(而无需拷贝数据)
CREATE TABLE IF NOT EXISTS mydb.employees2
LIKE mydb.employees;
SHOW TABLES;--查看当前库的所有表
SHOW TABLES IN mydb;--查看目标库的所有表
SHOW TABLES 'empl.*';--查看满足规则的所有表
DESCRIBE EXTENDED mydb.employees;--显示表的扩展属性
DESCRIBE FORMATTED mydb.employees;--格式化显示表的扩展属性
DESCRIBE mydb.employees.salary;--显示指定属性

管理表(内部表)

Hive 默认情况下会将这些表的数据存储在由配置项 hive.metastore.warehouse.dir (例如,/user/hive/warehouse) 所定义的目录的子目录下。当我们删除一个管理表时,Hive也会删除这个表中数据。

外部表

关键字 EXTENAL 创建 Hive外部表,LOCATION…子句则告诉Hive 数据位于哪个路径下。因为表是外部的,所以Hive并非认为其完全拥有这份数据。因此,删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉。

CREATE EXTERNAL TABLE IF NOT EXISTS stocks(
    exchange         STRING,
    symbol           STRING,
    ymd              STRING,
    price_open       FLOAT,
    price_high       FLOAT,
    price_low        FLOAT,
    volume           INT,
    price_adj_close  FLOAT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/data/stocks';
--表结构复制(而不会复制数据)
CREATE EXTERNAL TABLE IF NOT EXISTS mydb.employees3
LIKE mydb.employees
LOCATION '/path/to/data';
--如果语句中省略 EXTERNAL 关键字而且源表是外部表的话,那么生成的新表也将是外部表,如果语句中省略掉 EXTERNAL 关键字而且源表是管理表的话,那么生成的新表也将是管理表。但是如果语句中包含有 EXTERNAL 关键字而且原表是管理表的话,那么生成的新表是外部表,即使在这种场景下,LOCATION 子句同样是可选的。

分区管理表

分区关键字 PARTITIONED BY

CREATE TABLE employees(
    name          STRING,
    salary        FLOAT,
    subordinates  ARRAY<STRING>,
    deductions    MAP<STRING,FLOAT>,
    address       STRUCT<street:STRING, state:STRING, zip:INT>
)
PARTITIONED BY (country STRING, state STRING);
SHOW PARTITIONS employees;--查看分区信息
SHOW PARTITIONS employees PARTITION(country='US');--过滤查看分区

外部分区表

--创建外部分区表
CREATE EXTERNAL TABLE IF NOT EXISTS log_messages(
    hms            INT,
    severity       STRING,
    server         STRING,
    process_id     INT,
    message        STRING
)
PARTITIONED BY (year INT, month INT, day INT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

--添加分区
ALTER TABLE log_messages ADD PARTITION(year=2012, month=1, day=2)
LOCATION 'hdfs://...';

删除表

DROP TABLE IF EXISTS employees;
--对于外部表,表的元数据信息会被删除,但是表中的数据不会被删除。

修改表

ALTER TABLE 仅仅会修改表元数据,表数据本身不会有任何修改,需要用户自己确认所有的修改都和真实的数据是一致的。

--表重命名
ALTER TABLE log_messages RENAME TO logmsgs;

--增加、修改和删除表分区
ALTER TABLE log_messages ADD IF NOT EXISTS
PARTITION (year=2011, month=1, day=1) LOCATION '/logs/2011/01/01'
PARTITION (year=2011, month=1, day=2) LOCATION '/logs/2011/01/02'
PARTITION (year=2011, month=1, day=3) LOCATION '/logs/2011/01/03';

ALTER TABLE log_messages PARTITION(year=2011, month=12, day=2) SET LOCATION 's3n://...';--这个命令不会将数据从旧的路径转移走,也不会删除旧的数据。

ALTER TABLE log_messages DROP IF EXISTS PARTITION(year=2011, month=12, day=2);--管理表的话 会删除数据,外部表,分区内数据不会被删除。


--修改列信息
--即使字段名或者字段类型没有改变,用户也需要完全指定旧的字段名,并给出新的字段名及新的字段类型。
--将字段移动到第一个位置,那么只需要使用FIRST 替代 AFTER other_column子句即可
ALTER TABLE log_messages
CHANGE COLUMN hms hours_minutes_seconds INT
COMMENT 'The hours, minutes, and seconds part of the timestamp'
AFTER severity;

--增加列
ALTER TABLE log_messages ADD COLUMNS (
    app_name   STRING COMMENT 'Application name',
    session_id LONG COMMENT 'THE current session id'
); 

--删除或者替换列
--REPLACE 只能用于使用了2中内置SerDe模块的表:DynamicSerDe 或者 MetadataTypeColumnsetSerDe
ALTER TABLE log_messages REPLACE COLUMNS (
    hours_mins_secs   int COMMENT 'hour, minute, seconds from timestamp',
    severity          STRING COMMENT 'The message severity',
    message           STRING COMMENT 'The rest of the message'
);

--修改表属性
--用户可以增加附加的表属性或者修改已经存在的属性,但是无法删除属性。
ALTER TABLE log_messages SET TBLPROPERTIES (
    'notes' = 'The process id is no longer captured; this column is always NULL');


--修改存储属性
ALTER TABLE log_messages
PARTITION(year=2012, month=1, day=1)
SET FILEFORMAT SEQUENCEFILE;

--修改SerDe
ALTER TABLE table_using_JSON_storage
SET SERDE 'com.example.JSONSerDe'
WITH SERDEPROPERTIES(
    'prop1'='value1',
    'prop2'='value2'
);

--向一个已经存在着的 SerDe 增加新的 SERDEPROPERTIES 属性
ALTER TABLE table_using_JSON_storage
SET SERDEPROPERTIES(
    'prop3'='value3',
    'prop4'='value4'
);

--修改表语句 ALTER TABLE···TOUCH
--执行"钩子"的技巧,典型应用场景是Hive之外存储的文件被修改了,就会触发钩子的执行。例如,某个脚本往分区2012/01/01中写入了新的日志信息文件
ALTER TABLE log_message TOUCH
PARTITION(year=2012, month=1, day=1);

--修改表语句 ALTER TABLE···ARCHIVE PARTITION
--语句会将这个分区内的文件打成一个Hadoop压缩包(HAR)文件。但是这样仅仅可以降低文件系统中的文件数以及减轻NameNode的压力,而不会减少任何存储空间
--使用UNARCHIVE就可以进行反向操作。只能用于分区表中独立的分区
ALTER TABLE log_messages ARCHIVE
PARTITION(year=2012, month=1, day=1);


--修改表语句 ENABLE NO_DROP/OFFLINE
--ENABLE <-> DISABLE
ALTER TABLE log_messages
PARTITION(year=2012, month=1, day=1) ENABLE NO_DROP;--防止分区被删除
ALTER TABLE log_messages
PARTITION(year=2012, month=1, day=1) ENABLE OFFLINE;--防止分区被查询

HiveQL:数据操作

向管理表中装载数据

-- LOAD DATA LOCAL... 拷贝本地数据到位于分布式文件系统上的目标位置,而 LOAD DATA 转移数据到目标位置
-- OVERWRITE 关键词,使用OVERWRITE关键字,那么会先输出数据,在增加这条记录,如果没有这个关键字,会新增数据
LOAD DATA LOCAL INPATH '${ENV:HOME}/california-employees'
OVERWRITE INTO TABLE employees
PARTITION (COUNTRY='US', state='CA');

对于INPATH 子句中使用的文件路径还有一个限制,那就是这个路径下不可以包含任何文件夹。
Hive并不会验证用户装载的数据和表的模式是否匹配,然而,Hive会验证文件格式是否和表结构定义的一致

通过查询语句向表中插入数据

-- 从已经存在的表中导入数据
INSERT OVERWRITE TABLE employees
PARTITION (country = 'US', state = 'OR')
SELECT * FROM staged_employees se
WHERE se.cnty = 'US' AND se.st = 'OR';
--从已经存在的表中导入数据到分区表中
--INSERT OVERWRITE/INSERT INTO 可以混合使用
FROM staged_employees se
INSERT OVERWRITE TABLE employees
    PARTITION (country='US', state='OR')
    SELECT * WHERE se.cnty='US' AND se.st = 'OR'
INSERT OVERWRITE TABLE employees
    PARTITION (country='US', state='CA')
    SELECT * WHERE se.cnty='US' AND se.st = 'CA'
INSERT OVERWRITE TABLE employees
    PARTITION (country='US', state='IL')
    SELECT * WHERE se.cnty='US' AND se.st = 'IL';

-- 动态分区插入
-- Hive根据SELECT语句中最后2列来确定分区字段country和state的值。源表字段值和输出分区值之间的关系是根据位置而不是根据命名来匹配的。
INSERT OVERWRITE TABLE employees
PARTITION (country, state)
SELECT ..., se.cnty, se.st
FROM staged_employees se;

-- 动态分区、静态分区混合使用
-- 静态分区键必须出现在动态分区键之前
INSERT OVERWRITE TABLE employees
PARTITION (country = 'US', state)
SELECT ..., se.cnty, se.st
FROM staged_employees se WHERE se.cnty = 'US';

动态分区属性

单个查询语句中创建表并加载数据

--这里本身没有进行数据"装载",而是将元数据中指定一个指向数据的路径
CREATE TABLE ca_employees
AS SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';

导出数据

-- INSERT...DIRECTORY...
-- 一个或多个文件将会被写入到路径中,具体个数取决于调用的 reducer个数
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/ca_employees'
SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';


--指定输出文件夹目录
FROM staged_employees se
INSERT OVERWRITE DIRECTORY 'tmp/or_employees'
    SELECT * WHERE se.cty = 'US' and se.st = 'OR'
INSERT OVERWRITE DIRECTORY 'tmp/ca_employees'
    SELECT * WHERE se.cty = 'US' and se.st = 'CA'
INSERT OVERWRITE DIRECTORY 'tmp/IL_employees'
    SELECT * WHERE se.cty = 'US' and se.st = 'IL'
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值