建表
基本语句格式
CREATE [external] TABLE if not exists student #默认建立内部表,加上external则是建立外部表(id int COMMENT'学号',sname string COMMENT'用户名',age int COMMENT'年龄')#字段名称,字段类型,字段描述信息 COMMENT '记录学生学号'#表的描述信息PARTITION BY (department string COMMENT'根据部门分区')#设定分区的字段名称,此字段为全新字段,不得是表中任意字段;clustered BY (id,age)#指定分桶的字段,此字段必须来自表中字段;sorted BY (id ASC, age DESC)#指定一个桶内的排序规则(按照id升序,按照年龄降序);INTO 9 buckets #指定桶的个数为9ROW FORMAT delimited fields terminated BY '\t' #指定逗号为列分隔符collection items terminated by ',' #集合中的元素间的分隔符map keys terminated by ':' #元素内部的分隔符lines terminated BY '\n'#指定换行符为行分隔符stored AS textfile #指定最终表数据的存储格式,默认是textfile,还可以是rcfile(行列结合的格式)/parquet(压缩格式)location '/user/student' #指定hive上表在hdfs上的存储路径,默认的是配置路径下
1.内部表
CREATE TABLE if not exists student(id int ,sname string ,age int)
ROW FORMAT delimited FIELDS terminated BY ','
LINES terminated BY '\n';
2.外部表
CREATE external TABLE if not exists student(id int ,sname string ,age int)
ROW FORMAT delimited FIELDS terminated BY ','
LINES terminated BY '\n'
location '/user/student';
注意:
建外部表之后,若是从HDFS上加载数据的话(本质上是移动数据),会将数据从原路径移动到建表的路径下,
若两者路径不一致,则会导致其他部门的代码无法获取到数据,
因此,建立外部表的时候一定要location路径,且该路径与数据的原路径保持一致,
否则,会造成工作的重大失误!!!
3.分区表
CREATE TABLE if not exists student(id int ,sname string ,age int)
PARTITION BY (city string )
ROW FORMAT delimited FIELDS terminated BY ','
LINES terminated BY '\n';
4.分桶表
CREATE TABLE if not exists student(id int ,sname string ,age int)
clustered BY (id,age)
sorted BY (id ASC, age DESC)
INTO 9 buckets
ROW FORMAT delimited FIELDS terminated BY ','
LINES terminated BY '\n';
5.复制表
CREATE TABLE if not exists student01 LIKE student;
- 复制一个表结构和student一样的表,不复制数据
- 复制表student01是内部表还是外部表与student没关系,只与创建过程中是否指定了关键字external
6.查询表
CREATE TABLE if not exists student01 AS select id,sname FROM student;
查询出student表中的字段存入新建的表中,就叫查询表
数据类型详解
简单类型:
- string
- float
- int (4个字节的整数)
- bigint (8个字节的整数)
- smallint (2个字节的整数)
- tinyint (1个字节的整数)
复杂类型:
1)array:数组,存储多个元素,且元素是相同的数据类型,比如:beijing,shenzhen,wuhan
CREATE TABLE if not exists student(id int ,city array<string>)
ROW FORMAT delimited fields terminated BY '\t'
collection items terminated by ',';
查找时通过下标定位
SELECT city[0] FROM student; #输出:beijingSELECT city FROM student; #输出:[beijing,shenzhen,wuhan]
2)map:映射,比如:Chinese:80,math:90
CREATE TABLE if not exists student(id int ,score map<string,int>)
ROW FORMAT delimited fields terminated BY '\t'
collection items terminated by ','
map keys terminated by ':';
查找时通过key定位
SELECT score FROM student;
#输出:{Chinese:80,math:90} SELECT score['math'] FROM student; #输出:90
3)struct:结构体,存储多个元素,元素类型可以不同,比如:mengfan,man,180
CREATE TABLE if not exists student(id int ,remarks struct<name:string,sex:string,height:int>)
ROW FORMAT delimited fields terminated BY '\t'
collection items terminated by ','
查找时通过.查找具体的信息
SELECT remarks FROM student; #输出:{name:mengfan,sex:man,height:180}SELECT remarks.height FROM student; #输出:180
分隔符详解
1)列分隔符、元素分隔符、元素内分隔符、行分隔符的顺序
ROW FORMAT delimited fields terminated BY '\t' #指定空格为列分隔符
collection items terminated by ',' #集合中的元素间的分隔符
map keys terminated by ':' #元素内部的分隔符
lines terminated BY '\n'#指定换行符为行分隔符
比如:有一行数据: 0001 黄海霞,孟凡 语文:80,数学:90
空格是两列数据的分隔符,逗号是两个元素之间的分隔符,冒号是元素内部的分隔符
三种分隔符的顺序为:由外到内,顺序不可改变,行分隔符在最后;
2)多字节的分隔符
hive默认只能解析单字节分隔符,数据:0001::黄海霞::80
方法1:修改serde library,默认是lazysimpleserde,改为RegexSerDe
create table stu (id int,sname string,score string)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe' #指定序列化类库,正则表达式
with serdeproperties('input.regex'='(.*)::(.*)::(.*)' #定义输入的正则表达式 ,'output.format.string'='%1$s %2$S %3$S'); #定义输出的结果
注意:
- 数据中有多少个分隔符,表达式中就要有多少个(.*)::(.*)::(.*)
- 分隔符若是|,则需要用\\转义,(.*)\\|\\|(.*)\\|\\|(.*)
- 输出结果中的 %1$s 个数要与输入中的(.*)的个数对应
- (.*)代表的是任意字符
- $s 是占位符
方法2:修改hive底层源码,影响较大,其他使用单字节的文件容易出错,不推荐使用
查看表
SHOW tables#查看数据表 SHOW tables in hd_hive; #查看hd_hive库中的数据表 SHOW tables LIKE 's*'; #查看表名是以s开头的表 SHOW create table student; #查看student表的建表语句 SHOW PARTITIONS student; #查看student表的分区 SHOW PARTITIONS student PARTITION(city='beijing'); #查看student表的beijing分区DESC student; #查看表的字段信息 DESC formatted student; #查看元数据库中,表的字段信息(已格式化) DESC extended student; #查看元数据库中,表的详细信息(未格式化)
删除表
DROP TABLE IF EXISTS student; #删除表,包括表结构和表数据 TRUNCATE TABLE IF EXISTS student; #清空表,保留表结构,删除表数据
- 内部表:删除的时候,元数据库会删除,且HDFS上的原始数据也会被删除;
- 外部表:删除的时候,元数据库会删除,但HDFS上的原始数据不会被删除;
修改表
1.修改表名
ALTER TABLE student RENAME TO stu; #修改表名,student改为stu
2.修改表字段信息
ALTER TABLE student ADD COLUMNS(department string); #添加字段 ALTER TABLE student REPLACE COLUMNS(id int ,sname string); #替换表的所有列的字段 ALTER TABLE student CHANGE sname tname string; #修改字段名称,需同时指定新字段的类型ALTER TABLE student CHANGE age age string; #修改字段类型(有限制)int能转化成string,只能小转大,不可逆;但是hive1.2.2版本中没有这个限制
3.修改表分区信息
ALTER TABLE student ADD if not exists PARTITION (city='shanghai'); #添加分区 ALTER TABLE student ADD if not exists PARTITION (city='shenzhen') location '/user/student/shenzhen';#添加分区的同时指定路径 ALTER TABLE student DROP if exists PARTITION (city='beijing'); #删除分区
修改分区:
ALTER TABLE student PARTITION (city='shenzhen') SET location '/user/shenzhen'; #修改分区的路径 ALTER TABLE student PARTITION (city='shenzhen') ENABLE no_drop; #防止分区被删除 ALTER TABLE student PARTITION (city='shenzhen') ENABLE offline; #防止分区被查询
其他辅助命令
SHOW CREATE TABLE student; # 查看建表语句,将默认语句自动补全后的建表语句