分享

Hive SQL四大归类以及实操

问题导读
1.Hive创建表默认情况下会保存到什么数据库?
2.如何创建自定义格式的Hive?
3.通过什么命令,可以查看创建的表的信息比如分隔符等?
4.内部表和外部表在创建格式上有什么区别?
5.内外部表应用场景是什么?




Hive SQL我们可能经常看到DDL,DML等,他们具体代表什么意思,可能我们不懂。这里给我们详细介绍下,并且有相关的实践,供我们学习和参考。

SQL语言共分为四大类:
数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。


1. 数据查询语言DQL
数据查询语言DQL基本结构是由SELECT(select)子句,FROM(from)子句,WHERE(where)
子句组成的查询块:
SELECT <字段名表>
FROM <表或视图名>
WHERE <查询条件>


2 .数据操纵语言DML
数据操纵语言DML主要有三种形式:
1) 插入:INSERT(insert)
2) 更新:UPDATE(update)
3) 删除:DELETE(delete)


3. 数据定义语言DDL
数据定义语言DDL用来创建数据库中的各种对象-----表、视图、
索引、同义词、聚簇等如:

create    table      view    index     syn    cluster
CREATE   TABLE/   VIEW/  INDEX/   SYN/  CLUSTER
             |         |        |         |       |
             表     视图   索引  同义词  簇


4. 数据控制语言DCL
数据控制语言DCL用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等。如:
1) GRANT:授权。

2) ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一点。
回滚---ROLLBACK
回滚命令使数据库状态回到上次最后提交的状态。其格式为:
SQL>ROLLBACK;

3) COMMIT [WORK]:提交。

更多深度:
提交数据有三种类型:显式提交、隐式提交及自动提交。下面分
别说明这三种类型。
(1) 显式提交
用COMMIT命令直接完成的提交为显式提交。其格式为:
SQL>COMMIT;

(2) 隐式提交
用SQL命令间接完成的提交为隐式提交。这些命令是:
ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,
EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。

(3) 自动提交
若把AUTOCOMMIT设置为ON,则在插入、修改、删除语句执行后,
系统将自动进行提交,这就是自动提交。其格式为:
SQL>SET AUTOCOMMIT ON;

————————————————
上面有了基础知识,接着我们实操【附图文】

1、Hive DDL(数据库定义语言)
1.1、数据库的基本操作

[mw_shl_code=sql,true]--展示所有数据库
        show databases;
--切换数据库
        use database_name;
/*创建数据库               
        CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
          [COMMENT database_comment]
          [LOCATION hdfs_path]
          [WITH DBPROPERTIES (property_name=property_value, ...)];
*/
        create database test;
/*
        删除数据库        
        DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];        
*/
        drop database database_name;
[/mw_shl_code]
注意:当进入hive的命令行开始编写SQL语句的时候,如果没有任何相关的数据库操作,那么默认情况下,所有的表存在于default数据库,在hdfs上的展示形式是将此数据库的表保存在hive的默认路径下,如果创建了数据库,那么会在hive的默认路径下生成一个database_name.db的文件夹,此数据库的所有表会保存在database_name.db的目录下。

1.2、数据库表的基本操作


[mw_shl_code=sql,true]/*
        创建表的操作
                基本语法:
                CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name    --                         (Note: TEMPORARY available in Hive 0.14.0 and later)
                  [(col_name data_type [COMMENT col_comment], ... [constraint_specification])]
                  [COMMENT table_comment]
                  [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
                  [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)]                                 INTO num_buckets BUCKETS]
                  [SKEWED BY (col_name, col_name, ...)                  -- (Note: Available in Hive                         0.10.0 and later)]
             ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
             [STORED AS DIRECTORIES]
                  [
                           [ROW FORMAT row_format]
                           [STORED AS file_format]
                     | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]  --                                 (Note: Available in Hive 0.6.0 and later)
                  ]
                  [LOCATION hdfs_path]
                  [TBLPROPERTIES (property_name=property_value, ...)]   -- (Note: Available in Hive                         0.6.0 and later)
                  [AS select_statement];   -- (Note: Available in Hive 0.5.0 and later; not                                         supported for external tables)

                CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
                          LIKE existing_table_or_view_name
                  [LOCATION hdfs_path];
                 复杂数据类型
                data_type
                   : primitive_type
                   | array_type
                   | map_type
                   | struct_type
                   | union_type  -- (Note: Available in Hive 0.7.0 and later)
                 基本数据类型
                primitive_type
                  : TINYINT
                  | SMALLINT
                  | INT
                  | BIGINT
                  | BOOLEAN
                  | FLOAT
                  | DOUBLE
                   | DOUBLE PRECISION -- (Note: Available in Hive 2.2.0 and later)
                  | STRING
                  | BINARY      -- (Note: Available in Hive 0.8.0 and later)
                  | TIMESTAMP   -- (Note: Available in Hive 0.8.0 and later)
                  | DECIMAL     -- (Note: Available in Hive 0.11.0 and later)
                  | DECIMAL(precision, scale)  -- (Note: Available in Hive 0.13.0 and later)
                  | DATE        -- (Note: Available in Hive 0.12.0 and later)
                  | VARCHAR     -- (Note: Available in Hive 0.12.0 and later)
                  | CHAR        -- (Note: Available in Hive 0.13.0 and later)

                array_type
                  : ARRAY < data_type >

                map_type
                  : MAP < primitive_type, data_type >

                struct_type
                  : STRUCT < col_name : data_type [COMMENT col_comment], ...>

                union_type
                   : UNIONTYPE < data_type, data_type, ... >  -- (Note: Available in Hive 0.7.0 and                         later)
                 行格式规范
                row_format
                  : DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS                                 TERMINATED BY char]
                [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
               [NULL DEFINED AS char]   -- (Note: Available in Hive 0.13 and later)
                          | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value,                                 property_name=property_value, ...)]
                 文件基本类型
                file_format:
                  : SEQUENCEFILE
                  | TEXTFILE    -- (Default, depending on hive.default.fileformat configuration)
                  | RCFILE      -- (Note: Available in Hive 0.6.0 and later)
                  | ORC         -- (Note: Available in Hive 0.11.0 and later)
                  | PARQUET     -- (Note: Available in Hive 0.13.0 and later)
                  | AVRO        -- (Note: Available in Hive 0.14.0 and later)
                  | JSONFILE    -- (Note: Available in Hive 4.0.0 and later)
                  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
                 表约束
                constraint_specification:
                  : [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE ]
                    [, CONSTRAINT constraint_name FOREIGN KEY (col_name, ...) REFERENCES                                         table_name(col_name, ...) DISABLE NOVALIDATE
*/

[/mw_shl_code]

1.2.1、创建普通hive表(不包含行定义格式)

[mw_shl_code=sql,true]        create table psn
        (
        id int,
        name string,
        likes array<string>,
        address map<string,string>
        )
[/mw_shl_code]

20200621135410990.png

1.2.2、创建自定义行格式的hive表

[mw_shl_code=sql,true]create table psn2
        (
        id int,
        name string,
        likes array<string>,
        address map<string,string>
        )
        row format delimited
        fields terminated by ','
        collection items terminated by '-'
        map keys terminated by ':';
[/mw_shl_code]

1.2.3、创建默认分隔符的hive表( ^A、 ^B、 ^C)

[mw_shl_code=bash,true]        create table psn3
        (
        id int,
        name string,
        likes array<string>,
        address map<string,string>
        )
        row format delimited
        fields terminated by '\001'
        collection items terminated by '\002'
        map keys terminated by '\003';
[/mw_shl_code]

1.png

1.2.4、创建hive的外部表(需要添加external和location的关键字)
在之前创建的表都属于hive的内部表(psn,psn2,psn3),而psn4属于hive的外部表

[mw_shl_code=sql,true]        create external table psn4
        (
        id int,
        name string,
        likes array<string>,
        address map<string,string>
        )
        row format delimited
        fields terminated by ','
        collection items terminated by '-'
        map keys terminated by ':'
        location '/data';
[/mw_shl_code]

1.png


1.2.5、内部表跟外部表的区别:
&#8203; 1、hive内部表创建的时候数据存储在hive的默认存储目录中,外部表在创建的时候需要指定额外的目录
&#8203; 2、hive内部表删除的时候,会将元数据和数据都删除,而外部表只会删除元数据,不会删除数据

1.2.6、内外部表应用场景
类型
适用场景
内部表
需要先创建表,然后向表中添加数据,适合做中间表的存储
外部表
可以先创建表,再添加数据,也可以先有数据,再创建表。
本质上是将hdfs的某一个目录的数据跟hive的表关联映射起来,
因此适合原始数据的存储,不会因为误操作将数据给删除掉


1.2.7、创建单分区表
hive的分区表:
hive默认将表的数据保存在某一个hdfs的存储目录下,当需要检索符合条件的某一部分数据的时候,需要全量遍历数据,io量比较大,效率比较低。

因此可以采用分而治之的思想,将符合某些条件的数据放置在某一个目录,此时检索的时候只需要搜索指定目录即可,不需要全量遍历数据。

[mw_shl_code=sql,true]        create table psn5
        (
        id int,
        name string,
        likes array<string>,
        address map<string,string>
        )
        partitioned by(gender string)
        row format delimited
        fields terminated by ','
        collection items terminated by '-'
        map keys terminated by ':';
[/mw_shl_code]

1.png

1.2.8、创建多分区表

[mw_shl_code=sql,true]        create table psn6
        (
        id int,
        name string,
        likes array<string>,
        address map<string,string>
        )
        partitioned by(gender string,age int)
        row format delimited
        fields terminated by ','
        collection items terminated by '-'
        map keys terminated by ':';        
[/mw_shl_code]

1.png

注意:

当创建完分区表之后,在保存数据的时候,会在hdfs目录中看到分区列会成为一个目录,以多级目录的形式 存在
当创建多分区表之后,插入数据的时候不可以只添加一个分区列,需要将所有的分区列都添加值
多分区表在添加分区列的值得时候,与顺序无关,与分区表的分区列的名称相关,按照名称就行匹配


1.2.9、给分区表添加分区列的值

[mw_shl_code=sql,true]alter table table_name add partition(col_name=col_value)
[/mw_shl_code]

1.png

1.png

1.png

1.png

1.png

1.2.10、删除分区列的值
[mw_shl_code=sql,true]alter table table_name drop partition(col_name=col_value)
[/mw_shl_code]

1.png

1.png

注意:

添加分区列的值的时候,如果定义的是多分区表,那么必须给所有的分区列都赋值

1.png

删除分区列的值的时候,无论是单分区表还是多分区表,都可以将指定的分区进行删除

1.2.11、修复分区:
&#8203; 在使用hive外部表的时候,可以先将数据上传到hdfs的某一个目录中,然后再创建外部表建立映射关系,如果在上传数据的时候,参考分区表的形式也创建了多级目录,那么此时创建完表之后,是查询不到数据的,原因是分区的元数据没有保存在mysql中,因此需要修复分区,将元数据同步更新到mysql中,此时才可以查询到元数据。具体操作如下:

在hdfs创建目录并上传文件


[mw_shl_code=bash,true]        hdfs dfs -mkdir /test
          hdfs dfs -mkdir /test/age=10
          hdfs dfs -mkdir /test/age=20
          hdfs dfs -put /root/data/data /test/age=10
          hdfs dfs -put /root/data/data /test/age=20
[/mw_shl_code]

创建外部表
[mw_shl_code=sql,true]create external table psn7
          (
          id int,
          name string,
          likes array<string>,
          address map<string,string>
          )
          partitioned by(age int)
          row format delimited
          fields terminated by ','
          collection items terminated by '-'
          map keys terminated by ':'
          location '/test';
[/mw_shl_code]

查询结果(没有数据)
[mw_shl_code=sql,true]select * from psn7;
[/mw_shl_code]

修复分区
[mw_shl_code=sql,true]msck repair table psn7;
[/mw_shl_code]

查询结果(有数据)
[mw_shl_code=sql,true]select * from psn7;
[/mw_shl_code]

问题
以上面的方式创建hive的分区表会存在问题,每次插入的数据都是人为指定分区列的值,我们更加希望能够根据记录中的某一个字段来判断将数据插入到哪一个分区目录下,此时利用我们上面的分区方式是无法完成操作的,需要使用动态分区来完成相关操作,后续讲解。

2、Hive DML
2.1、插入数据
2.1.1、Loading files into tables
  • 记载数据文件到某一张表中
语法:
[mw_shl_code=sql,true]LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2 ...)]

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
[PARTITION (partcol1=val1, partcol2=val2 ...)] [INPUTFORMAT 'inputformat' SERDE 'serde'] (3.0 or later)
[/mw_shl_code]

  • 加载本地数据到hive表

load data local inpath '/root/data/data' into table psn;
(/root/data/data指的是本地linux目录)


1.png

  • 加载hdfs数据文件到hive表

load data inpath '/data/data' into table psn2;
(/data/data指的是hdfs的目录)

注意:
1、load操作不会对数据做任何的转换修改操作
2、从本地linux load数据文件是复制文件的过程
3、从hdfs load数据文件是移动文件的过程
4、load操作也支持向分区表中load数据,只不过需要添加分区列的值
5、对于数据格式,hive是读时检查,mysql是写时检查

2.1.1、Inserting data into Hive Tables from queries


从查询语句中获取数据插入某张表
语法:

[mw_shl_code=sql,true]Standard syntax:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)                         [IF NOT EXISTS]] select_statement1 FROM from_statement;
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)]                                 select_statement1 FROM from_statement;

Hive extension (multiple inserts):
FROM from_statement
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)                         [IF NOT EXISTS]] select_statement1
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]]                                                         select_statement2]
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] ...;
        FROM from_statement
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)]                                 select_statement1
[INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2]
[INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]]                                                         select_statement2] ...;

Hive extension (dynamic partition inserts):
        INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2]                                 ...) select_statement FROM from_statement;
        INSERT INTO TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...)                                 select_statement FROM from_statement;
[/mw_shl_code]

从表中查询数据插入结果表,如下

[mw_shl_code=sql,true]INSERT OVERWRITE TABLE psn9 SELECT id,name FROM psn
[/mw_shl_code]

从表中获取部分列插入到新表中,如下

[mw_shl_code=sql,true]        from psn
        insert overwrite table psn9
        select id,name
        insert into table psn10
        select id
[/mw_shl_code]

注意:这种方式插入数据的时候需要预先创建好结果表

2.1.1、Writing data into the filesystem from queries
将查询到的结果插入到文件系统中
语法:

[mw_shl_code=sql,true]Standard syntax:
                INSERT OVERWRITE [LOCAL] DIRECTORY directory1
                  [ROW FORMAT row_format] [STORED AS file_format] (Note: Only available starting                         with Hive 0.11.0)
                  SELECT ... FROM ...

        Hive extension (multiple inserts):
                FROM from_statement
                INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1
                [INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...
                row_format
                  : DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS                         TERMINATED BY char]
        [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
        [NULL DEFINED AS char] (Note: Only available starting with Hive 0.13)
[/mw_shl_code]

将查询到的结果导入到hdfs文件系统中

[mw_shl_code=sql,true]insert overwrite directory '/result' select * from psn;
[/mw_shl_code]

将查询的结果导入到本地文件系统中

[mw_shl_code=sql,true]insert overwrite local directory '/result' select * from psn;
[/mw_shl_code]

注意:路径千万不要填写根目录,会把所有的数据文件都覆盖

2.1.2、Inserting values into tables from SQL
这种方式使用传统关系型数据库的方式插入数据,效率较低
语法:

[mw_shl_code=sql,true]Standard Syntax:
                INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)]                         VALUES values_row [, values_row ...]
  
        Where values_row is:
                ( value [, value ...] )
                where a value is either null or any valid SQL literal
[/mw_shl_code]

插入数据

[mw_shl_code=sql,true]        insert into psn values(1,'zhangsan');
[/mw_shl_code]

2.2、数据更新和删除


1.png

1.png

在官网中我们明确看到hive中是支持Update和Delete操作的,但是实际上,是需要事务的支持的,Hive对于事务的支持有很多的限制,如下图所示:


1.png

因此,在使用hive的过程中,我们一般不会产生删除和更新的操作,如果你需要测试的话,参考下面如下配置:


[mw_shl_code=xml,true]//在hive的hive-site.xml中添加如下配置:
        <property>
                <name>hive.support.concurrency</name>
                <value>true</value>
        </property>
        <property>
                <name>hive.enforce.bucketing</name>
                <value>true</value>
        </property>
        <property>
                <name>hive.exec.dynamic.partition.mode</name>
                <value>nonstrict</value>
        </property>
        <property>
                <name>hive.txn.manager</name>
                <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
        </property>
        <property>
                <name>hive.compactor.initiator.on</name>
                <value>true</value>
        </property>
        <property>
                <name>hive.compactor.worker.threads</name>
                <value>1</value>
        </property>
//操作语句
        create table test_trancaction (user_id Int,name String) clustered by (user_id) into 3                         buckets stored as orc TBLPROPERTIES ('transactional'='true');
        create table test_insert_test(id int,name string) row format delimited fields                                   TERMINATED BY ',';
        insert into test_trancaction select * from test_insert_test;
        update test_trancaction set name='jerrick_up' where id=1;
//数据文件
        1,jerrick
        2,tom
        3,jerry
        4,lily
        5,hanmei
        6,limlei
        7,lucky
[/mw_shl_code]



原文链接:https://blog.csdn.net/weixin_42191996/article/details/88085103

已有(1)人评论

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条