文档章节

Hive 表操作(HIVE的数据存储、数据库、表、分区、分桶)

o
 osc_ogi0qclx
发布于 2019/08/23 20:06
字数 1715
阅读 7
收藏 0

精选30+云产品,助力企业轻松上云!>>>

1、Hive的数据存储

Hive的数据存储基于Hadoop HDFS

Hive没有专门的数据存储格式

存储结构主要包括:数据库、文件、表、试图

Hive默认可以直接加载文本文件(TextFile),还支持sequence file

创建表时,指定Hive数据的列分隔符与行分隔符,Hive即可解析数据。

 

2、Hive的数据模型-数据库

类似传统数据库的DataBase

默认数据库"default"

使用#hive命令后,不使用hive>use <数据库名>,系统默认的数据库。可以显式使用hive> use default;

 

创建一个新数据库

hive > create database test_dw;

 

3、Hive的数据模型-表

  • Table 内部表

与数据库中的 Table 在概念上是类似

每一个 Table 在 Hive 中都有一个相应的目录存储数据。例如,一个表 test,它在 HDFS 中的路径为:$HIVE_HOME/warehouse/test。warehouse是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir}  指定的数据仓库的目录

所有的 Table 数据(不包括 External Table)都保存在这个目录中。

内部表,删除表时,元数据与数据都会被删除

 

具体操作如下:

创建数据文件inner_table.dat

 

创建表

hive>create table inner_table (key string);

加载数据

hive>load data local inpath '/usr/local/inner_table.dat' into table inner_table;

查看数据

select * from inner_table

select count(*) from inner_table

删除表

drop table inner_table

 

  • External Table 外部表
  1. 指向已经在 HDFS 中存在的数据,可以创建 Partition
  2. 它和 内部表 在元数据的组织上是相同的,而实际数据的存储则有较大的差异
  3. 内部表 的创建过程和数据加载过程(这两个过程可以在同一个语句中完成),在加载数据的过程中,实际数据会被移动到数据仓库目录中;之后对数据对访问将会直接在数据仓库目录中完成。删除表时,表中的数据和元数据将会被同时删除
  4. 外部表只有一个过程,加载数据和创建表同时完成,并不会移动到数据仓库目录中,只是与外部数据建立一个链接。当删除一个 外部表 时,仅删除该链接

具体实例如下:

CREATE EXTERNAL TABLE page_view

( viewTime INT,

 userid BIGINT,

 page_url STRING,

 referrer_url STRING,

 ip STRING COMMENT 'IP Address of the User',

 country STRING COMMENT 'country of origination‘

)

 COMMENT 'This is the staging page view table'

 ROW FORMAT DELIMITED FIELDS TERMINATED BY '44' LINES TERMINATED BY '12'

 STORED AS TEXTFILE

 LOCATION 'hdfs://hadoop:9000/user/data/staging/page_view';

 

创建数据文件external_table.dat

 

创建表

hive>create external table external_table1 (key string)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\t'

location '/home/external';

 

HDFS创建目录/home/external:

#hadoop fs -put /home/external_table.dat /home/external

 

加载数据

LOAD DATA INPATH '/home/external_table1.dat' INTO TABLE external_table1;

 

查看数据

select * from external_table

select count(*) from external_table

 

删除表

drop table external_table

 

内部表与外部表的区别:

外部表只删除表信息(元数据信息),不删除数据;内部表会删除表信息和数据信息

 

  • Partition  分区表

 

分区表相关命令:

SHOW TABLES; # 查看所有的表

SHOW TABLES '*TMP*'; #支持模糊查询

SHOW PARTITIONS TMP_TABLE; #查看表有哪些分区

DESCRIBE TMP_TABLE; #查看表结构

 

Partition 对应于数据库的 Partition 列的密集索引

Hive 中,表中的一个 Partition 对应于表下的一个目录,所有的 Partition 的数据都存储在对应的目录中

例如:test表中包含 date 和 city 两个 Partition,

则对应于date=20130201, city = bj 的 HDFS 子目录为:

/warehouse/test/date=20130201/city=bj

对应于date=20130202, city=sh 的HDFS 子目录为;

/warehouse/test/date=20130202/city=sh

 

具体操作:

CREATE TABLE tmp_table #表名

(

title   string, # 字段名称 字段类型

minimum_bid     double,

quantity        bigint,

have_invoice    bigint

)COMMENT '注释:XXX' #表注释

 PARTITIONED BY(pt STRING) #分区表字段(如果你文件非常之大的话,采用分区表可以快过滤出按分区字段划分的数据)

ROW FORMAT DELIMITED

FIELDS TERMINATED BY '\001'   # 字段是用什么分割开的

STORED AS SEQUENCEFILE; #用哪种方式存储数据,SEQUENCEFILE是hadoop自带的文件压缩格式

 

创建数据文件partition_table.dat

创建表

create table partition_table(rectime string,msisdn string)

partitioned by(daytime string,city string)

row format delimited

fields terminated by '\t' stored as TEXTFILE;

加载数据到分区

load data local inpath '/home/partition_table.dat' into table partition_table partition (daytime='2013-02-01',city='bj');

查看数据

select * from partition_table

select count(*) from partition_table

删除表

drop table partition_table

 

alter table partition_table add partition (daytime='2013-02-04',city='bj');

通过load data 加载数据

 

alter table partition_table drop partition (daytime='2013-02-04',city='bj')

元数据,数据文件删除,但目录daytime=2013-02-04还在

 

  • Bucket  Table 桶表

桶表是对数据进行哈希取值,然后放到不同文件中存储。

创建表

create table bucket_table(id string) clustered by(id) into 4 buckets;

加载数据

set hive.enforce.bucketing = true;

insert into table bucket_table select name from stu;

insert overwrite table bucket_table select name from stu;

数据加载到桶表时,会对字段取hash值,然后与桶的数量取模。把数据放到对应的文件中。

 

抽样查询

select * from bucket_table tablesample(bucket 1 out of 4 on id);

 

  • 视图的创建

create view v1 AS select * from t1;

 

  • 表的操作

表的修改

Alter table target_tab add columns(cols,string);

 

表的删除

Drop table;

 

  • 导入数据

当数据被加载至表中时,不会对数据进行任何转换。Load 操作只是将数据复制/移动至 Hive 表对应的位置。

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE]
    INTO TABLE tablename
    [PARTITION (partcol1=val1, partcol2=val2 ...)]

把一个Hive表导入到另一个已建Hive表

INSERT OVERWRITE TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement FROM from_statement

CTAS

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

(col_name data_type, ...) …

AS SELECT …

例:create table new_external_test as  select * from external_table1;

 

  • 表的查询

SELECT [ALL | DISTINCT] select_expr, select_expr, ...

FROM table_reference

[WHERE where_condition]

[GROUP BY col_list]

[ CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list] | [ORDER BY col_list] ]

[LIMIT number]

 

基于Partition的查询  

一般 SELECT 查询是全表扫描。但如果是分区表,查询就可以利用分区剪枝(input pruning)的特性,类似“分区索引“”,只扫描一个表中它关心的那一部分。Hive 当前的实现是,只有分区断言(Partitioned by)出现在离 FROM 子句最近的那个WHERE 子句中,才会启用分区剪枝。例如,如果 page_views 表(按天分区)使用 date 列分区,以下语句只会读取分区为‘2008-03-01’的数据。

 SELECT page_views.*    FROM page_views    WHERE page_views.date >= '2013-03-01' AND page_views.date <= '2013-03-01'

LIMIT Clause

Limit 可以限制查询的记录数。查询的结果是随机选择的。下面的查询语句从 t1 表中随机查询5条记录:

SELECT * FROM t1 LIMIT 5

Top N查询

 

下面的查询语句查询销售记录最大的 5 个销售代表。

SET mapred.reduce.tasks = 1
  SELECT * FROM sales SORT BY amount DESC LIMIT 5

 

  • 表的连接

导入ac信息表

hive> create table acinfo (name string,acip string)  row format delimited fields terminated by '\t' stored as TEXTFILE;

hive> load data local inpath '/home/acinfo/ac.dat' into table acinfo;

内连接

select b.name,a.* from dim_ac a join acinfo b on (a.ac=b.acip) limit 10;

左外连接

select b.name,a.* from dim_ac a left outer join acinfo b on a.ac=b.acip limit 10;

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

Springboot+Redis综合运用/缓存使用

项目引入依赖(安装redis自行百度) <!-- spring-boot redis --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactI......

心田已荒
46分钟前
10
0
puppeteer csdn 登录 [失败, 跨域cookie无法解决]

使用 puppeteer 登录csdn 暂时没能解决这个问题 滑块可以滑到右边 原因在于cookie const puppeteer = require('puppeteer');const uid = '===';const pwd = '===';(async () => { ......

阿豪boy
今天
17
0
即使使用__init__.py,也如何解决“尝试以非软件包方式进行相对导入”

问题: I'm trying to follow PEP 328 , with the following directory structure: 我正在尝试使用以下目录结构来遵循PEP 328 : pkg/ __init__.py components/ core.py __init_......

富含淀粉
今天
19
0
Java线程池

前言 Java中对线程池的抽象是ThreadPoolExecutor类,Executors是一个工具类,内置了多种创建线程池的方法: newFixedThreadPool:固定长度线程池 newCachedThreadPool :可缓存线程池 newSin...

nullpointerxyz
今天
57
0
Python笔记:用Python制作二维码

这些年,二维码在我国的日常使用频率特别大。因为其具有简单及安全性吧!除了用网络工具制作二维码,其实用JavaScript或Python也可以制作二维码,而且更有个性。 示例一(制作普通黑白二维码...

tengyulong
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部