Hive 是一个构建在Hadoop之上的数据仓库和分析工具,她提供了一种类SQL的查询语言--HiveQL, 用于将结构化的查询SQL 转换为MapReduce 任务和Tez任务, 通过Hadoop的分布式计算能力来执行查询任务。同步hive 可以将hdfs文件中的数据,同步到外表中,进行数据分析。
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name (
column1 data_type,
column2 data_type,
...
)
[COMMENT 'table_comment']
[PARTITIONED BY (partition_column data_type, ...)]
[CLUSTERED BY (col_name, col_name, ...)
[SORTED BY (col_name [ASC|DESC], ...)]
INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[TBLPROPERTIES (property_name=property_value, ...)]
[LOCATION 'hdfs_path'];
Hive 使用HiveQL的建表语句,DDL 来定义表结构。DDL可以用于创建、修改、删除Hive表的元数据,包括表名、列定义、分区定义、存储格式等。 这里的发部分语法与标准的SQL建表语句还是相同的。
外部表(External Table):
它和数据存储(如HDFS)中的文件并没有直接的关联。Hive仅通过指定文件的位置来了解数据的结构。
管理表(Managed Table):
管理表是在Hive中定义的表,它的数据和表定义都由Hive管理。
对于外部表,可以使用LOAD DATA
语句来加载数据,而对于管理表,可以使用常规的INSERT INTO
语句来插入数据。
分区是把一个表的数据以分区字段的值作为目录去存储。可以缩小磁盘数据扫描范围,减少IO; 将数据存储在多个分区目录下,便于地利管理数据。
静态分区语法:
#分区表创建
#单分区表创建
CREATE TABLE tmp_xx(id int,name String) partitioned by (d string);
#多分区表创建
CREATE TABLE tmp_xx(id int,name String) partitioned by (d String,h String);
#添加分区
ALTER TABLE tmp_partition ADD IF NOT EXISTS PARTITION (d='20220628')
#删除分区
ALTER TABLE tmp_partition DROP IF EXISTS PARTITION (d='20220628')
#数据写入
#单分区数据写入
INSERT OVERWRITE TABLE tmp_xx PARTITION (d='20220629')
SELECT id, name FROM tmp_yy limit 10;
#多分区数据写入
INSERT OVERWRITE TABLE tmp_xx PARTITION (d='20220629',h='15')
SELECT id, name FROM tmp_yy limit 10;
#查看分区数据
#单分区
select * from tmp_xx where d='20220629'
#多分区
select * from tmp_xx where d='20220629' and h='15'
#查看表分区
show partitions table;
#查看目录
hadoop dfs -du -h /user/hive/warehouse/tmp_xxx
动态分区语法:
1、使用动态分区需要hive开启动态分区:
-- 开启动态分区 默认为false,不开启
set hive.exec.dynamic.partition=true;
-- 指定动态分区模式,默认为strict
set hive.exec.dynamic.partition.mode=nonstrict;
# 下面参数可选
SET hive.exec.max.dynamic.partitions=2048;
SET hive.exec.max.dynamic.partitions.pernode=256;
SET hive.exec.max.created.files=10000;
SET hive.error.on.empty.partition=true;
2、语法:
#写入数据
INSERT overwrite TABLE tmp_partition PARTITION(d)
SELECT id,NAME,d FROM tmp_xxx
#写入多分区数据
INSERT overwrite TABLE tmp_partition PARTITION(d,h)
SELECT id,NAME,d,h FROM tmp_xxx
#混合分区使用,使用动态分区和静态分区,静态分区必须在前
INSERT overwrite TABLE tmp_partition PARTITION(d='20220629',h)
SELECT id,NAME,h FROM tmp_xxx
相比于分区表, 分桶表是将数据进行更加细粒度的划分, 一般使用较少,在数据量不大的情况下, 使用分桶甚至会使性能更差。
分桶表将整个数据内容按照分桶字段的哈希值进行区分,使用该哈希值除以桶的个数得到取余数,bucket_id = column.hashcode % bucket.num,余数决定了该条记录会被分在哪个桶中。余数相同的记录会分在一个桶里。需要注意的是,在物理结构上,一个桶对应一个文件,而分区表只是一个目录,至于目录下有多少数据是不确定的。
创建分桶表:
CREATE TABLE tmp_bucket(id INT,NAME STRING) clustered BY (id) INTO 4 buckets
抽样:
#建表
select columns from table tablesample(bucket x out of y on column);
-- x:表示从第几个分桶进行抽样
-- y:表示每隔几个分桶取一个分桶,y必须为表bucket的整数倍或者因子
#从分桶表的建表语句中可知,我们一共分了4个桶,所以我们这里x取1,y取2
一共抽取2(4/2)个桶,从第一个桶开始,每隔2个桶抽取一次,即第一个桶和
第三个桶。
SELECT id,NAME FROM tmp_bucket tablesample(bucket 1 OUT of 2 ON id) LIMIT 10
Hive中的索引是基于Hadoop分布式文件系统(HDFS)的存储布局来实现的。它在HDFS上创建了元数据文件来跟踪数据文件的位置和分区信息。
hive索引原理:
为了方便理解,我们将Hive的索引和MySQL的索引做一下对比:
存储方式:
数据类型支持:
数据一致性:
查询性能:
管理和维护:
-- 创建索引
CREATE [UNIQUE] INDEX index_name
ON TABLE table_name
[PARTITIONED BY (col_name, ...)] -- 指定索引列
[index_type]
[AS index_properties]
[WITH DEFERRED REBUILD]
[STORED AS index_storage_handler]
[TBLPROPERTIES (property_name=property_value, ...)]
[COMMENT 'index_comment'];
UNIQUE
: 可选关键字,用于指定索引是否是唯一索引。PARTITIONED BY (col_name, ...): 指定索引列
index_type
: 索引类型,例如BTREE或BITMAP。这是可选的,如果未指定,默认是BTREE类型。AS index_properties
: 可选参数,用于指定索引的配置属性。这些属性通常与底层存储引擎相关,一般使用 org.apache.hadoop.hive.ql.index.compact.CompactIndexHandlerWITH DEFERRED REBUILD
: 可选参数,用于启用延迟重建索引,即当前是个空索引,还没有实际创建爱你索引。当此选项被使用时,需要手动进行重建,索引将在创建后被标记为“DEFERRED_REBUILD” 。STORED AS index_storage_handler
: 可选参数,用于指定存储索引的处理程序。例如,可以指定STORED AS RCFILE来存储索引为RCFile格式。 TBLPROPERTIES (property_name=property_value, ...)
: 可选参数,用于指定额外的表级属性,这些属性通常与底层存储引擎相关。COMMENT 'index_comment'
: 可选参数,用于提供索引的注释信息。刚创建完的Hive索引表是没有数据的,需要生成索引数据
alter index 索引名称 on 表名 rebuild;
生成索引的过程可能会对系统资源产生一定的影响,特别是对于大型数据集和庞大的索引来说。因此,在生成索引时需要考虑系统的负载和可用资源。
3、查看索引
SHOW FORMATTED INDEX ON table_name;
SHOW FORMATTED INDEXES ON table_name;