创建表
首先看一个🌰
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] `default`.`video_all`(
`cuid` string,
`totalpv` int COMMENT '总 pv',
`activedays` int COMMENT '活跃天数',
`firstday` string,
`lastday` string
)
PARTITIONED BY (
`day` string COMMENT 'partition_stat_date SAMPLE 20160124'
)
CLUSTERED BY (`cuid`)
SORTED BY (`cuid` desc)
INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LOCATION
'hdfs://yq01-build-hdfs.dmop.baidu.com:54310/user/midway/video_statistics/monthly'
create table语法和sql语句非常类似,特别的是以下几点
1.external可选:external为外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),创建外部表仅记录数据所在的路径,不对数据的位置做任何改变,删除外部表时也只删除元数据,不会删除表中的数据;不选external时,会将数据移动到数据仓库指向的路径,删除时数据跟着被删除掉。
2.PARTITIONED BY 分区方式
根据某一个key(不在create table里面)对数据进行分区,如本例中,体现在HDFS上就是 table目录下有多个不同的分区文件夹,eg:hdfs://yq01-build-hdfs.dmop.baidu.com:54310/user/midway/video_statistics/monthly/20160124
3.ROW FORMAT DELIMITED FIELDS TERMINATED BY
hive没有严格的格式要求,只需要指定文件中列分隔和行分隔方式即可
4.CLUSTERED BY
除partition之外,还可以通过cluster进行分桶。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。好处有:1.查询效率更高;2.取样更方便
修改表
#增加分区
ALTER TABLE `default`.`video_all` ADD PARTITION (day='20190401')
#表重命名
ALTER TABLE `default`.`video_all` RENAME TO `video_eg`
#增加/更新列
ALTER TABLE `default`.`video_all` ADD COLUMNS (user_type string)
#插入(若重复则覆盖)
INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...
#select
SELECT [ALL | DISTINCT] select_expr, select_expr, ...
FROM table_reference
[WHERE where_condition]
[GROUP BY col_list [HAVING condition]]
[CLUSTER BY col_list
| [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]
]
[LIMIT number]
#join
SELECT a.* FROM a JOIN b ON (a.id = b.id)
语法基本和sql类似,需要注意的是,MapReduce的执行方式:
1.order by:全局排序,因而只有一个reducer。数据规模大时,时延较久
2.sort by:可以是多个reducer,当reducer设置大于1时,保证每个reducer中的排序
3.distribute by:根据指定的内容将数据分到同一个reducer
4.cluster by = distribute by + sort by
4.join by:
a.如果join中多个表的 join key 是同一个,则 join 会被转化为单个 map/reduce 任务
b.不同join key,则有几个join key,则有几个map/reduce任务
c.reducer 会缓存 join 序列中除了最后一个表的所有表的记录,再通过最后一个表将结果序列化到文件系统。这一实现有助于在 reduce 端减少内存的使用量。实践中,应该把最大的那个表写在最后(否则会因为缓存浪费大量内存)。
保存select结果
#新创建表存数据
create table new_table
as
select * from old_table
#插入已存在的表
insert into new_table
select col_0, col_1 from old_table
#存入特定路径
insert overwrite [local] directory '/home/hadoop/test'
select * from old_table;
网友评论