赞
踩
create database if not exists test_001;
使用数据库
use test_001;
说明:hive 的表存放位置模式是由 hive-site.xml 当中的一个属性指定的,默认是存放在该配置文件设置的路径下,也可在创建数据库时单独指定存储路径。
hive.metastore.warehouse.dir
/user/hive/warehouse
create database test_002 location ‘/user/hive/warehouse/hfc01.db’;
数据库有一些描述性的属性信息,可以在创建时添加:
create database test_003 with dbproperties(‘owner’=‘Candy_W’,‘date’=‘20211101’,‘env’=‘beta’)
desc database extended test_003;
与mysql查询语句是一样的语法
#查看所有数据库
show databases;
删除一个空数据库,如果数据库下面有数据表,那么就会报错
drop database test_002;
强制删除数据库,包含数据库下面的表一起删除(请谨慎操作)
drop database test_002 cascade;(级联删除;和数据一样)
[]里的属性为可选属性,不是必须的,但是如果有可选属性,会使 sql 语句的易读性更好,更标准与规范。
例如:[comment ‘字段注释信息’][comment ‘表的描述信息’]等,[external]属性除外
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name(
column_name data_type [comment ‘字段注释信息’]
column_name data_type [comment ‘字段注释信息’]
…
[comment ‘表的描述信息’]
[PARTITIONED BY(column_name data_type, …)]
[CLUSTERED BY (column_name, column_name, …)
[SORTED BY(col_name [ASC|DESC], …)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION ‘指定表在 hdfs 中的存储路径’]
)
如果创建的表名已存在,则不会再创建,也不会抛出异常提示:表已存在。否则则自动创建该表。
外部表在创建时必须同时指定一个指向实际数据的路径(LOCATION),Hive在创建内部表时,会将数据移动到数据仓库指向的路径;
若创建外部表,仅记录数据所在的路径,不对数据的位置作任何改变。
内部表在删除后,其元数据和数据都会被一起删除。
外部表在删除后,只删除其元数据,数据不会被删除。
COMMENT
用于给表的各个字段或整张表的内容作解释说明的,便于他人理解其含义。
PARTITIONED BY
区分表是否是分区表的关键字段,依据具体字段名和类型来决定表的分区字段。
CLUSTERED BY
依据column_name对表进行分桶,在 Hive 中对于每一张表或分区,Hive 可以通过分桶的方式将数据以更细粒度进行数据范围划分。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
SORTED BY
指定表数据的排序字段和排序规则,是正序还是倒序排列。
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’
指定表存储中列的分隔符,这里指定的是’\t’,也可以是其他分隔符。
STORED AS SEQUENCEFILE|TEXTFILE|RCFILE
指定表的存储格式,如果文件数据是纯文本格式,可以使用STORED AS TEXTFILE,如果数据需要压缩,则可以使用STORED AS SEQUENCEFILE。
LOCATION
指定 Hive 表在 hdfs 里的存储路径,一般内部表(Managed Table)不需要自定义,使用配置文件中设置的路径即可。
如果创建的是一张外部表,则需要单独指定一个路径。
create table if not exists t_student
(
id int,
s_name string,
s_age int)
partitioned by(date string)
row format delimited fields terminated by ‘\t’;
以换行进行;也可以使用‘,’
2. 使用create table … as select…语句创建表
例子:
create table sub_student as select * from t_student;
使用 create table … as select …语句来创建新表sub_student,此时sub_student 表的结构及表数据与 t_student 表一模一样,相当于直接将 t_student 的表结构和表数据复制一份到 sub_student 表。
注意:
(1). select 中选取的列名(如果是 * 则表示选取所有列名)会作为新表 sub_student 的列名。
(2). 该种创建表的方式会改变表的属性以及结构,例如不能是外部表,只能是内部表,也不支持分区、分桶。
如果as select后的表是分区表,并且使用select *,则分区字段在新表里只是作为字段存在,而不是作为分区字段存在。
在使用该种方式创建时,create 与 table 之间不能加 external 关键字,即不能通过该种方式创建外部目标表,默认只支持创建内部目标表。
(3). 该种创建表的方式所创建的目标表存储格式会变成默认的格式textfile。
3.使用like语句创建表
例子:
create table sub1_student like t_student;
注意:
(1). 只是将 t_student 的表结构复制给 sub1_student 表。
(2). 并不复制 t_student 表的数据给 sub1_student 表。
(3). 目标表可以创建为外部表,即:
create external(外部的) table sub2_student like t_student;
大量的hive查询任务,如果用交互式shell来进行输入的话,显然效率及其低下,因此,生产中更多的是使用脚本化运行机制:
该机制的核心点是:hive可以用一次性命令的方式来执行给定的hql语句
[root@hadoop06 ~]# hive -e “use db_order; select * from student;”
然后,进一步,可以将上述命令写入shell脚本中,以便于脚本化运行hive任务,并控制、调度众多hive任务,示例如下:
[root@hd2 ~] vi t_order_etl.sh
代码如下:
#!/bin/bash
hive -e “select * from db_order.t_order”
hive -e “select * from default.t_user”
hql=“create table default.t_bash as select * from db_order.t_order”
hive -e “$hql”
shell 可以直接用:
[root@hd2 ~] sh t_order_et1.sh
create table students
(
id bigint,
name string,
age int,
school string,
class string
)
#指定分隔符(下面语句表示数据以逗号分隔开)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’
#手动指定该内部表表格创建在HDFS下的/user/hive/warehouse目录内,也可以不指定,默认存放/user/hive/warehouse下
内部表数据存储的位置是hive在hdfs中存在默认的存储路径,即default数据库(默认:/user/hive/warehouse)
内部表的数据是Hive自身管理,创建内部表时,会将数据移动到数据仓库指向的路径
alter table table_name set tblproperties(‘EXTERNAL’=‘TRUE’);
可以通过 desc formatted 表名 来查看表的属性
删除内部表会直接删除元数据(metadata)及存储数据,对内部表的修改会将修改直接同步给元数据
内部表:
create table stu1(id int,name string,age int,address string)
row format delimited fields terminated by ‘,’;
缺点:在删除表的时候,数据会跟着表一起被删除掉,容易造成数据的丢失
create external table students
(
id bigint,
name string,
age int,
school string,
class string
)
#指定分隔符(下面语句表示数据以逗号分隔开)
ROW FORMAT DELIMITED FIELDS TE
RMINATED BY ‘,’
#手动指定该内部表表格创建在HDFS下的/user/hive/warehouse_external 目录内
LOCATION '/user/hive/warehouse_external ';
例子
create external table stu2(id int,name string,age int,address string)
row format delimited fields terminated by ‘,’
location ‘/external/stus2’;
外部表数据存储的位置可以自己指定,指定除/user/hive/warehouse以外的路径。
外部表数据由HDFS管理,创建外部表时,仅记录数据所在的路径,不对数据的位置做任何改变。
alter table table_name set tblproperties(‘EXTERNAL’=‘FALSE’);
可以通过 desc formatted 表名 来查看表的属性
修改即可;
删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name)
1.加载数据到表中:
load data local inpath ‘/root/students1.txt’ into table stu2;
然后我们把这个stu3删除了;你会发现,我们一会创建一个表stu3如果字段一样;数据还在;他们共享了数据;
只要他们的外部目录不一样就不共享;
外部表:external 不会自动在内部表中创建
create external table stu2(id int,name string,age int,address string)
row format delimited fields terminated by ‘,’
location ‘/external/stus2’;
create external table stu3(id int,name string,age int,address string)
row format delimited fields terminated by ‘,’
location ‘/external/stus3’;
优点:在删除表的时候,数据不会跟着表一起被删除掉,安全性高
因为hive内部表在删除表是同时删除表数据与元数据,而外部表删除的时候,仅仅会删除元数据,HDFS上的文件并不会被删除,所以外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。
如果所有的数据都由hive处理,则创建内部表;如果数据的处理由hive和其他工具一起处理,则创建外部表。
我们在管理表不方便和其他工作共享数据。可以创建一个外部表指向这份数据,而并不需要对其具有所有权。
我们在使用hive内部表与外部表的时候,需要根据合适的业务场景去选择!
Hive分区表对应的是HDFS上独立的文件夹,该文件夹存放的是该分区的所有数据,其实分区就是分目录。
Hive通过分区把一个大的数据集根据业务需要分割成小的数据集,在查询时能够通过where关键词选择指定分区,从而提高查找效率。为什么这样能够提高查找效率呢?其实是因为Hive存放的数据是没有索引的,如果没有建立分区直接查询,Hive就会暴力查询,效率很低,所以通过分区能很好提高Hive的查询效率。分区还能够更加方便的管理一些特殊数据,例如一些日志数据,可以是一个天一个分区或者一个月一个分区,视数据量而定,这样就能很好地管理日志数据了。
分区表的实质是:在表目录中为数据文件创建分区子目录,以便于在查询时,MR程序可以针对分区子目录中的数据进行处理,缩减读取数据的范围。
比如,网站每天产生的浏览记录,浏览记录应该建一个表来存放,但是,有时候,我们可能只需要对某一天的浏览记录进行分析
这时,就可以将这个表建为分区表,每天的数据导入其中的一个分区;
当然,每日的分区目录,应该有一个目录名(分区字段)
create table t_partition(id int,name string,age int,address string)
partitioned by (dt string) //可以放入的是日期;但是习惯上使用string也可以
row format delimited fields terminated by ‘,’;
注意:分区字段不能是表定义中的已存在字段; 独立加入即可;
使用上面的导入数据方式加入导入到分区中即可:
这样我们查询的时候可以单独的使用dt 来查询;
select *from t_partition where dt=‘2022-6-10’; 查询的是6-10号的数据
这里可以使用时间戳来进行;
使用函数进行统计指定条件的: 加入了条件就是 10条;
不指定条件的查询操作:就是所有数据;
方式1:导入数据的一种方式:
手动用hdfs命令,将文件放入表目录;
方式2:在hive的交互式shell中用hive命令来导入本地数据到表目录
hive>load data local inpath ‘/root/order.data.2’ into table t_order;
方式3:用hive命令导入hdfs中的数据文件到表目录
hive>load data inpath ‘/access.log.2017-08-06.log’ into table t_access;
注意:导本地文件和导HDFS文件的区别:
本地文件导入表:复制
hdfs文件导入表:移动
1.将hive表中的数据导出到指定路径的文件(把hive分析之后的结果,给写出去)
将hive表中的数据导入HDFS的文件
insert overwrite directory ‘/root/access-data’
row format delimited fields terminated by ‘\t’
select name,age from t_partition;
或者我们想把部分数据存储到hdfs中的文件中;
测试证明,使用了overwrite参数会将你指定的这个目录下的所有内容全部覆盖掉!!!而不是只有当与你要导出的数据文件已经存在时才会覆盖。
但是尝试把overwrite参数去掉再去导出数据时,发现报错了:
FAILED: ParseException line 1:7 cannot recognize input near ‘insert’ ‘local’ ‘directory’ in insert clause
后来还是加上overwrite之后才可以执行成功,所以初步认为overwrite在导出数据时是必须要加上的参数。因此我们在导出hive的数据时,尽量找一个空目录。要注意,数据导出时列与列之间默认是不分隔的。
要解决这个问题:
首先的把这个所有的零散的文件进行合并;例如;先在有好多个文件内容;我们先把他合并在一起; 一个文件中;那就把这个文件进行导入即可;
例子:我们创建多个文件 a.txt; b.txt;c.txt; 然后合并文件内容;
把这文件进行合并在一个新文件中;一定不要使用工具打开;他打开是空白;
cat data/* >> xindata.txt 把data这个目录中的文件全部合并到xindata.txt 这个文件中;
然后把这个新数据传递给hive中;
这个操作以后,可以把一个月的数据都写到一个文件中;然后进行统计;
如果不要了;就直接删除即可;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。