修改表结构
将表t1的列名name 修改为username ,增加列注释 new name
alter table t1 change column name username string comment 'new name';
增加列
alter table t1 add colums(gender string)
删除列,不建议这么做,可以重新创建一个表
假设t1原来有name,age,sex三列,下面语句删除了age列
alter table t1 rep;ace columns(name string,sex int);
这里删除了表的元数据,但是表里的数据存在hdfs上,并没有删除,select * from t1 数据会有问题,因为表只有两列,而表里的数据还是有三列,所以会把原来age的数据解析为sex的值
表类型
管理表 ,也称为内部表,表的数据在hdfs上
desc formatted t1 ;
会显示Table Type: MANAGED_TABLE
drop内部表,表里的数据也会删除
指定表数据存放的位置(不指定,默认是在/usr/hive/warehouse)
create table t3(id int)location '/home/t3';
内部表转换为外部表(删除表是数据还在)
alter table t3 set tblproperties('EXTERNAL'='TRUE')
注意:EXTERNAL'='TRUE必须大写,小写虽然不会报错,但不会生效
外部表,删除表后,hdfs的数据还在,以后新建表,只要表名一样,表的数据还在
创建外部表
create external table t5(id int);
将数据上传至hadoop的t5表下,查询t5表就有数据了
hadoop fs -put log /user/hive/warehouse/t5
分区表
分区可以理解为分类,通过分类把不同类型的数据放到不同的目录下。
分类的标准就是分区字段,可以一个,也可以多个。
分区表的意义在于优化查询。查询时尽量利用分区字段。如果不使用分区字段,就会全部扫描。
create table t2(name string ,age int) partitioned by (class string)
增加分区字段
alter table t2 add partition(class='job1');
查看分区
show partitions t2;
向分区中上传数据
hadoop fs put log /user/hive/warehouse/t2/class=job1
查看分区中的数据
select * from t2 where class='job1'
还可以指定分区的路径
alter table t2 add partition(class='job1') location /tables/t2/job1
如果在hdfs上新建目录/user/hive/warehouse/t2/class=job2,再向该目录下上传数据,虽然hdfs上有class=job2这个目录,但是show partitions t2 显示不出job2这个分区,也不能从job2这个分区中查出数据,所以还是需要增加t2的job2分区
hadoop fs put log /user/hive/warehouse/t2/class=job2/
alter table t2 add partition(class='job2')
删除分区
alter table t2 drop partition(class='job2')
设置分区不能被删除
alter table t2 partition(class='job2') enable no_drop;
设置分区可以被删除
alter table t2 partition(class='job2') disable no_drop;
设置分区不能被查询
alter table t2 partition(class='job2') enable offline
设置分区不能被查询后,不能执行select * from t2,必须指定分区 ,比如select * from t2 where class='job1'
设置分区能被查询
alter table t2 partition(class='job2') disable offline
创建多级分区表
create table t3(id int) partitioned by (class string,city string);
增加分区
alter table t3 add partition(class='job1',city='sh');
上传数据
hadoop fs -put log /user/hive/warehouse/t3/class=job1/city=sh
查询数据
select * from t3 where class='job1' and city='sh';
桶表是对数据进行哈希取值,然后放到不同文件中存储。
创建表
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值,然后与桶的数量取模。把数据放到对应的文件中。
注意:
物理上,每个桶就是表(或分区)目录里的一个文件
一个作业产生的桶(输出文件)和reduce任务个数相同
桶表的抽样查询
select * from bucket_table tablesample(bucket 1 out of 4 on id);
tablesample是抽样语句
语法解析:TABLESAMPLE(BUCKET x OUT OF y)
y必须是table总bucket数的倍数或者因子。
hive根据y的大小,决定抽样的比例。
例如,table总共分了64份,当y=32时,抽取(64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据。x表示从哪个bucket开始抽取。
例如,table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据,分别为第3个bucket和第(3+16=)19个bucket的数据。
hive 视图的操作
使用视图可以降低查询的复杂度
视图的创建
create view v1 as select t1.name from t1;
show tables 可以查看多以v1表
视图的删除
drop view if exists v1;
查询视图,视图不存储数据,查询数据还是从表t1中查询
select * from v1;
hive 索引的操作
创建索引
create index t1_index on table t1(id) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild in table t1_index_table;
as指定索引器, index t1_index是索引名称,on table t1(id) 表示对表t1中的id字段建立索引,t1_index_table是索引信息存储表
重建索引
alter index t1_index on t1 rebuild;
重建之后会执行mapreduce程序,遍历表中的数据建立索引,重建完成之后可以执行select * from t1_index_table 查看产生的索引信息
显示索引
show formatted index on t1;
删除索引
drop index if exists t1_index on t1;
从本地文件中装载数据
[OVERWRITE] INTO TABLE t2 [PARTITION (province='beijing')];
从hdfs中转载数据
load data inpath '/path/data' [overwrite] into table t2 [partition(province='beijing')];
实际上是将hdfs的/path/data的数据移动到/user/hive/warehouse/t2/province=beijing/目录下
通过查询表装载数据
INSERT OVERWRITE TABLE t2 PARTITION (province='beijing') SELECT * FROM xxx WHERE xxx
FROM t4 INSERT OVERWRITE TABLE t3 PARTITION (class='cl1') SELECT id,age WHERE name='ww'
INSERT OVERWRITE TABLE t3 PARTITION (class='cl2') SELECT id,age WHERE name='kk'
INSERT OVERWRITE TABLE t3 PARTITION (class='cl3') SELECT id,age WHERE name='wk'
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
PARTITIONED BY
CLUSTERED BY
SORTED BY
SKEWED BY (col_name, col_name, ...) ON ([(col_value, col_value, ...), ...|col_value, col_value, ...])
STORED AS DIRECTORIES] ]
ROW FORMAT
STORED AS file_format] | STORED BY
LOCATION
TBLPROPERTIES
[AS select_statement] (Note: not supported when creating external tables.)
hive表可以映射到别的集群的hdfs上面,只要在location的地方写hdfs的绝对路径
CREATE EXTERNAL TABLE `kafka_hive_daily_count_old`(
`db_name` string COMMENT 'database name',
`tb_partition` string COMMENT 'table&partition',
`num_rows` string COMMENT 'record count')
PARTITIONED BY (
`inc_day` string)
ROW FORMAT SERDE
'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS INPUTFORMAT
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
'hftp://10.116.77.16:50070/result/o_inc_sgs_core/dm_kafka_hive_daily_count'
TBLPROPERTIES (
'transient_lastDdlTime'='1487728687')