美文网首页大数据整理
Hadoop开发--Hive--DDL

Hadoop开发--Hive--DDL

作者: 无剑_君 | 来源:发表于2019-11-29 15:40 被阅读0次

    一、 DDL 操作

    启动服务:

     hive --service metastore &
     hive --service hiveserver2 &
    

    (一)数据库操作

    1. 创建数据库

    CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
      [COMMENT database_comment]
      [LOCATION hdfs_path]
      [WITH DBPROPERTIES (property_name=property_value, ...)];
    

    默认:创建的数据库将放在hdfs:/user/hive/warehouse
    在Hive数据库是一个命名空间或表的集合。
    在这里,IF NOT EXISTS是一个可选子句,通知用户已经存在相同名称的数据库。可以使用SCHEMA 在DATABASE的这个命令。下面的查询执行创建一个名为userdb数据库:

    0: jdbc:hive2://192.168.71.130:10000> CREATE DATABASE IF NOT EXISTS userdb;
    OK
    No rows affected (0.139 seconds)
    
    

    0: jdbc:hive2://192.168.71.130:10000> CREATE SCHEMA IF NOT EXISTS userdb;
    OK
    No rows affected (0.06 seconds)
    
    

    下面的查询用于验证数据库列表:

    0: jdbc:hive2://192.168.71.130:10000> SHOW DATABASES;
    OK
    +----------------+
    | database_name  |
    +----------------+
    | default        |
    | userdb         |
    +----------------+
    2 rows selected (0.051 seconds)
    
    
    数据表存放位置
    数据表存放位置

    2. 使用数据库

    USE database_name;

    0: jdbc:hive2://192.168.71.130:10000> USE userdb;
    OK
    No rows affected (0.049 seconds)
    
    

    3. 删除数据库

    DROP DATABASE是删除所有的表并删除数据库的语句。它的语法如下:

    DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];
    

    假设要删除的数据库名称为userdb。

    0: jdbc:hive2://192.168.71.130:10000> DROP DATABASE IF EXISTS userdb;
    OK
    No rows affected (0.141 seconds)
    
    

    使用CASCADE查询删除数据库。这意味着要全部删除相应的表在删除数据库之前。

    # 在数据库中创建表
    0: jdbc:hive2://192.168.71.130:10000> create table employees(name string,sex char(10),age int,salary float,address varchar(50));
    OK
    No rows affected (0.39 seconds)
    
    0: jdbc:hive2://192.168.71.130:10000> DROP DATABASE IF EXISTS userdb CASCADE;
    OK
    No rows affected (1.755 seconds)
    
    

    使用SCHEMA查询删除数据库。

    0: jdbc:hive2://192.168.71.130:10000> DROP SCHEMA userdb;
    

    4. 修改数据库

    (二)创建表

    create Table是用于在Hive中创建表的语句。
    语法

    CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.] table_name
    
    [(col_name data_type [COMMENT col_comment], ...)]
    [COMMENT table_comment]
    [ROW FORMAT row_format]
    [STORED AS file_format]
    

      Hive中的表可以分为托管表外部表,托管表的数据会存储在数据仓库目录下,由Hive管理,外部表的数据在指定位置,不在Hive的数据仓库中,只是在Hive元数据库中注册。
      创建外部表采用create external tablename方式创建,并在创建表的同时指定表的位置。
    假设需要使用CREATE TABLE语句创建一个名为employee表。下表列出了employee表中的字段和数据类型:
    编号 字段名称 数据类型
    1 Eid int
    2 Name String
    3 Salary Float
    4 Designation string

    Eid 编号
    Name 员工姓名
    Salary 工资
    Designation 任命管理人员

    1. 创建托管表

    CREATE TABLE IF NOT EXISTS employee ( eid int, name String,salary String, destination String)
    COMMENT '员工信息'
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '\t'
    LINES TERMINATED BY '\n'
    STORED AS TEXTFILE;
    

    说明:
    字段分隔符为:\t
    行分隔为 \n
    存储类型为:textfile

    保存文件类型:
    文件类型为:textfile

    create table users(id int) stored as textfile;
    

    表注释:

    COMMENT 'Employee details'
    # 表注释
    create table users(id int) comment 'users table';
    

    2. 外部表

    可以使用关键字EXTERNAL和LOCATION创建不存储在默认位置中的表,其中LOCATION指定了表存在HDFS上的位置。外部表在LOCATION已经存在数据时会派上用场,当删除一个EXTERNAL表时,表中的数据不会在文件系统删除

    现在HDFS存在/user/Hadoop/iis/input/iis.log文件,在该位置上创建外部表:

    hive>  create external table item(log string) location '/data/input';
    
    hive> select * from users;  
    

    可以看到,Hive将HDFS上的数据直接加载到了表中了。

    3. 临时表

    表只对当前session有效,session退出后,表自动删除。

    CREATE TEMPORARY TABLE IF NOT EXISTS employee ( eid int, name String, salary String, destination String);
    
    insert into employee values(1,'lihaonan','100.3','test')
    
    0: jdbc:hive2://192.168.71.130:10000> select * from employee;
    OK
    +---------------+----------------+------------------+-----------------------+
    | employee.eid  | employee.name  | employee.salary  | employee.destination  |
    +---------------+----------------+------------------+-----------------------+
    | 1             | lihaonan       | 100.3            | test                  |
    +---------------+----------------+------------------+-----------------------+
    1 row selected (0.5 seconds)
    
    
    1. LIKE创建表
      用Like创建表的语法为:
    CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name  
    LIKE existing_table_or_view_name  
    [LOCATION hdfs_path];  
    

    Like语法可以精确地根据现存表的定义定义目标表(不复制数据),如:
    创建一个新表,结构与其他一样

    hive> create table 新表名 like 原表名;
    

    Hive-0.8.0版本及之后的版本,CREATE TABLE LIKE view_name采用视图的schema创建表,并使用默认的SerDe和文件格式。
    SerDe是Serialize/Deserilize的简称,目的是用于序列化和反序列化。
    示例:

     create table emp like employee;
    
    
    1. create-table-as-select
      可以使用create-table-as-select (CTAS)语句创建表并加载查询结果到表中。该语句的操作是原子性,即直到所有查询结果被加载到表中之前,表对于其他用户是不可见的。所以其他用户要么看见带完整查询结果的表,要么根本看不见表。
      CTAS有CREATE和SELECT两部分,SELECT部分可以是任何被Hive支持的select语句,CREATE采用SELECT部分的schema并且创建带有其它表属性如SerDe和存储格式的目标表。如果SELECT部分没有指定所查询列的别名,目标表的列名将自动分配为_col0, _col1, 和 _col2等,否则按照别名命名目标表的列名。CTAS有几个限制:
      目标表不能是分区表
      目标表不能是外部表
    create external table temp as select * from employee; 
    

    目标表不能是list bucketing表
    正确示例:

    create table temp as select * from employee;
    

    (三)修改表

    基本语法:
    声明接受任意属性,我们希望在一个表中修改以下语法。

    ALTER TABLE name RENAME TO new_name
    ALTER TABLE name ADD COLUMNS (col_spec[, col_spec ...])
    ALTER TABLE name DROP [COLUMN] column_name
    ALTER TABLE name CHANGE column_name new_name new_type
    ALTER TABLE name REPLACE COLUMNS (col_spec[, col_spec ...])
    
    
    1. 重命名表
      Rename To… 语句
      重命名表,把 employee 修改为 emp。
    ALTER TABLE employee RENAME TO emp;
    
    1. 改变列名/类型/位置/注释
      语法:
    ALTER TABLE table_name CHANGE
    [CLOUMN] col_old_name col_new_name column_type
    [CONMMENT col_conmment]
    [FIRST|AFTER column_name];
    

    这个命令可以修改表的列名,数据类型,列注释和列所在的位置,FIRST将列放在第一列,AFTER col_name将列放在col_name后面一列。
    数据的列名和列数据类型:

    # 改变列名
    ALTER TABLE employee CHANGE name ename String;
    # 改变数据类型
    ALTER TABLE employee CHANGE salary salary Double;
    
    1. 增加/更新列
      基本语法:
    ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [CONMMENT col_comment], ...);
    
    

    ADD COLUMNS允许用户在当前列的末尾,分区列之前添加新的列,REPLACE COLUMNS允许用户更新列,更新的过程是先删除当前的列,然后在加入新的列。注:只有在使用native的SerDE时才可以这么做。
    增加了一个列名dept在employee表。

    ALTER TABLE employee ADD COLUMNS (dept STRING COMMENT 'Department name');
    
    1. 增加表的属性
    # 设置字段分隔属性为逗号
    alter table emp set serdeproperties('field.delim'=',');
    
    
    1. 修改表文件格式和组织
    修改表的文件格式
    ALTER TABLE table_name SET FILEFORMAT file_format;
    
    ALTER TABLE table_name CLUSTERED BY (col_name, col_name, ...)
    [SORTED By (col_name, ...)] INTO num_buckets BUCKETS;
    上面两个命令都修改了表的物理属性。
    

    (四)删除表

    语法如下:

    DROP TABLE [IF EXISTS] table_name;
    

    以下查询删除一个名为 employee 的表:

    DROP TABLE IF EXISTS employee;
    

      当对一个表进行Drop操作时,不仅会删除表中的数据还会删除表的元数据。如果HDFS配置了Trash,那么删除的数据会移动到.Trash/当前目录下,元数据则会彻底丢失。当删除EXTERNAL表时,表中的数据不会从文件系统中删除,也即文件系统中的数据不会随着EXTERNAL表的删除而删除。当删除被视图应用的表时,不会提示警告信息(视图不再有效,必须被另行删除或者被用户重建)。从Hive-0.7.0开始,DROP操作在表不存在时返回错误,除非使用了IF EXISTS或者配置参数hive.exec.drop.ignorenonexistent被设置为true。

    (五)分区表

      就是在系统上建立文件夹,把分类数据放在不同文件夹下面,加快查询速度。
      分区是表的部分列的集合,可以为频繁使用的数据建立分区,这样查找分区中的数据时就不需要扫描全表,这对于提高查找效率很有帮助.
      Hive组织表到分区。它是将一个表到基于分区列,如日期,城市和部门的值相关方式。使用分区,很容易对数据进行部分查询。
      表或分区是细分成桶,以提供额外的结构,可以使用更高效的查询的数据。桶的工作是基于表的一些列的散列函数值。
      一个名为employee表包含雇员数据,如 id, name, dept 和yoj (即入职年份)。假设需要检索所有在2012年加入,查询搜索整个表所需的信息员工的详细信息。但是,如果用年份分区雇员数据并将其存储在一个单独的文件,它减少了查询处理时间。

    1. 添加分区

    可以通过添加分区表改变所述表。假设我们有一个表叫employee ,拥有如 Id, Name, Salary, Designation, Dept, 和 yoj等字段。
    语法:

    ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec
    [LOCATION 'location1'] partition_spec [LOCATION 'location2'] ...;
    
    partition_spec:
    : (p_column = p_col_value, p_column = p_col_value, ...)
    

    以下查询用于将分区添加到employee表。

    hive> ALTER TABLE employee  ADD PARTITION (year=’2013’)  location '/2012/part2012';
    

    一个表可以有一个或者多个分区列,Hive将会为分区列上的每个不同的值组合创建单独的数据目录。分区列是虚拟列,要避免分区列名和数据列名相同,可以基于分区列进行查询。

    hive> create table people(name string, age int, birthday date, telephone string, address string) partitioned by(name string, age int);  
    FAILED: SemanticException [Error 10035]: Column repeated in partitioning columns  
    

    上面出现的错误是因为分区列和数据列名称相同了,此时要么修改数据列名要么修改分区列名。

    hive> create table people(name string, age int, birthday date, telephone string, address string) partitioned by(department string, sex string, howOld int);  
    

    建立分区后,会在相应的表目录下建立以分区名命名的目录,目录下是分区的数据。
    注意:表中的列不能和partition中的列重合了。

    2. 静态分区

    Hive分区是在创建表的时候用Partitioned by 关键字定义的,但要注意,Partitioned by子句中定义的列是表中正式的列,但是Hive下的数据文件中并不包含这些列,因为它们是目录名。

    create table par_tab (name string,nation string) partitioned by (sex string) row format delimited fields terminated by ',';
    

    1) 导入数据:

    准备本地数据文件par_tab.txt,内容 “名字/国籍”,将以性别(sex)作为分区:
    把数据插入到表(其实load操作相当于把文件移动到HDFS的Hive目录下):

    hive> load data local inpath '/root/par_tab.txt' into table par_tab partition (sex='man');
    

    查询:

    hive> select * from par_tab;
    徐魁元,china
    梁  胜,america
    陈  杰,china
    张文凯,china
    王凯月,japan
    尹懋宁,japan
    

    查看par_tab目录结构:

    hive> dfs -lsr /user/hive/warehouse/par_tab;
    

    再插入另一个数据文件数据,如文件:

    刘丽丽,china
    衣  洁,china
    
    hive> load data local inpath '/root/par_tab_wm.txt' into table par_tab partition (sex='woman');
    

    最后查看两次插入的结果,包含了man和woman:

    hive> select * from par_tab;
    

    因为分区列是表实际定义的列,所以查询分区数据时:

    hive> select * from par_tab where sex='woman';
    

    查看分区内容:

    hive> desc par_tab;
    

    2) 多个分区

    创建一张静态分区表par_tab_muilt,多个分区(性别+日期):

    hive> create table par_tab_muilt (name string, nation string) partitioned by (sex string,dt string) row format delimited fields terminated by ',' ;
    

    导入数据:

    hive> load data local inpath '/root/par_tab.txt' into table par_tab_muilt partition (sex='man',dt='2017-03-29');
    hive> dfs -lsr /user/hive/warehouse/par_tab_muilt;
    

    新建表的时候定义的分区顺序,决定了文件目录顺序(谁是父目录谁是子目录),正因为有了这个层级关系,当我们查询所有man的时候,man以下的所有日期下的数据都会被查出来。如果只查询日期分区,但父目录sex=man和sex=woman都有该日期的数据,那么Hive会对输入路径进行修剪,从而只扫描日期分区,性别分区不作过滤(即查询结果包含了所有性别)。

    2. 动态分区

    根据查询得到的数据动态分配到分区里。其实动态分区与静态分区区别就是不指定分区目录,由系统自己选择。

    1)启动动态分区功能
    hive> set hive.exec.dynamic.partition=true;
    

    假设已有一张表par_tab,前两列是名称name和国籍nation,后两列是分区列,性别sex和日期dt:

    hive> select * from par_tab_muilt;
    
    梁  胜  america man     2017-03-29
    陈  杰  china   man     2017-03-29
    张文凯  china   man     2017-03-29
    王凯月  japan   man     2017-03-29
    尹懋宁  japan   man     2017-03-29
    徐魁元  china   man     2017-03-29
    

    把这张表的内容直接插入到另一张表par_dnm中,并实现sex为静态分区,dt动态分区(不指定到底是哪日,让系统自己分配决定)。

    2)创建动态分区

    把这张表的内容直接插入到另一张表par_dnm中,并实现sex为静态分区,dt动态分区(不指定到底是哪日,让系统自己分配决定)。
    现在我把这张表的内容直接插入到另一张表par_dnm中,并实现sex为静态分区,dt动态分区(不指定到底是哪日,让系统自己分配决定);

    hive> insert overwrite table par_dnm partition(sex='man',dt)
        > select name, nation, dt from par_tab_muilt;
    

    插入后看下目录结构,再查看分区数。

    hive> show partitions par_dnm;
    

    注意,动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。
    动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数hive.exec.dynamic.partition.mode :

    hive> set hive.exec.dynamic.partition.mode;
    hive.exec.dynamic.partition.mode=strict
    

    它的默认值是strick,即不允许分区列全部是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,但是由于疏忽忘记为主分区列指定值了,这将导致一个dml语句在短时间内创建大量的新的分区(对应大量新的文件夹),对系统性能带来影响。
    所以我们要设置:

    hive> set hive.exec.dynamic.partition.mode=nostrick;
    

    3. 查看分区结构

    hive> show partitions 表名;
    

    4. 重命名分区

    语法

    ALTER TABLE table_name PARTITION 原分区 RENAME TO PARTITION 新分区;
    

    以下查询用来命名一个分区:

    hive> ALTER TABLE employee PARTITION (year=’1203’)
    > RENAME TO PARTITION (Yoj=’1203’);
    

    5. 删除分区

    删除分区:

    ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec, PARTITION partition_spec,...;
    

    以下查询是用来删除分区:

    hive> ALTER TABLE employee DROP [IF EXISTS] PARTITION (year=’1203’);
    

    (六)桶表

      桶表是对数据进行哈希取值,然后放到不同文件中存储。
      数据加载到桶表时,会对字段取hash值,然后与桶的数量取模。把数据放到对应的文件中。
      物理上,每个桶就是表(或分区)目录里的一个文件,一个作业产生的桶(输出文件)和reduce任务个数相同。
      可以把表或分区组织成桶,桶是按行分开组织特定字段,每个桶对应一个reduce操作。在建立桶之前,需要设置“hive.enforce.bucketing”属性为true,使Hive能够识别桶。
    作用:
    桶表专门用于抽样查询,是很专业性的,不是日常用来存储数据的表,需要抽样查询时,才创建和使用桶表。

    1. 启用桶
    hive>set hive.enforce.bucketing=true;
    hive>set hive.enforce.bucketing;
    
    1. 创建桶
    hive>create table btest2(id int,name string) clustered by(id) into 3 buckets
    row format delimited fields terminated by '\t';
    
    

    向桶中插入数据,这里按照用户id分了三个桶,在插入数据时对应三个reduce操作,输出三个文件。

    hive>insert overwrite table btest2 select * from userinfo;
    

    查看数据仓库下的桶目录,三个桶对应三个目录。

    hive>dfs –ls /user/hive/warehouse/btest2;
    

    Hive使用对分桶所用的值进行hash,并用hash结果除以桶的个数做取余运算的方式来分桶,保证了每个桶中都有数据,但每个桶中的数据条数不一定相等。

    hive>dfs –cat /user/hive/warehouse/btest2/*0_0;
    hive>dfs –cat /user/hive/warehouse/btest2/*1_0;
    hive>dfs –cat /user/hive/warehouse/btest2/*2_0;
    

    分桶可以获得比分区更高的查询效率,同时分桶也便于对全部数据进行采样处理。

    hive>select * from btest2 tablesample(bucket 1 out of 3 on id);
    
    1. 插入数据
    insert table 桶表名 select * from 表名; 
    

    请不要使用Load data插入数据,因为使用load data,没有启动mapreduce对数据进行哈希取值,只是简单的原样导入,没有起到抽样查询的目的。

    (七)截断表

    基本语法:

    TRUNCATE TABLE table_name [PARTITION partition_spec];  
    partition_spec:  
      : (partition_col = partition_col_value, partition_col = partiton_col_value, 
    

    当进行truncate操作时将会从一个表或者分区中删除所有的行,用户可以通过指定partition_spec删除多个分区,省略partition_spec将会删除表中的所有分区。
    truncate 不能删除外部表!因为外部表里的数据并不是存放在Hive Meta store中.

    truncate table 表名;
    

    二、数据类型

    1. 列类型

    1)字符类型:

    字符串类型的数据类型可以使用单引号('')或双引号("")来指定。它包含两个数据类型:VARCHAR和CHAR。Hive遵循C-类型的转义字符。
    各种CHAR数据类型:

    数据类型 长度
    VARCHAR 1 to 65355
    CHAR 255
    STRING
    2)日期类型:
    日期

    DATE值在年/月/日的格式形式描述 {{YYYY-MM-DD}}.

    转换类型 结果
    cast(date as date) Same date value
    cast(date as string) The year/month/day represented by the Date is formatted as a string in the form ‘YYYY-MM-DD’.
    cast(date as timestamp) A timestamp value is generated corresponding to midnight of the year/month/day of the date value, based on the local timezone.
    cast(string as date) If the string is in the form ‘YYYY-MM-DD’, then a date value corresponding to that year/month/day is returned. If the string value does not match this formate, then NULL is returned.
    cast(timestamp as date) The year/month/day of the timestamp is determined, based on the local timezone, and returned as a date value.
    时间戳(timestamp)

    它支持传统的UNIX时间戳可选纳秒的精度。它支持的java.sql.Timestamp格式“YYYY-MM-DD HH:MM:SS.fffffffff”和格式“YYYY-MM-DD HH:MM:ss.ffffffffff”。

    支持传统的UNIX时间戳和可选的纳秒精度。

    • 支持的转化:
    • 整数数字类型:以秒为单位解释为UNIX时间戳
    • 浮点数值类型:以秒为单位解释为UNIX时间戳,带小数精度
    • 字符串:符合JDBC java.sql.Timestamp格式“YYYY-MM-DD HH:MM:SS.fffffffff”(9位小数位精度)

    3)联合类型:

    联合是异类的数据类型的集合。可以使用联合创建的一个实例。语法和示例如下:

    UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>
    {0:1} 
    {1:2.0} 
    {2:["three","four"]} 
    {3:{"a":5,"b":"five"}} 
    {2:["six","seven"]} 
    {3:{"a":8,"b":"eight"}} 
    {0:9} 
    {1:10.0}
    
    

    4) 数值类型

    整型

    默认情况下,整数型为INT型,当数字大于INT型的范围时,会自动解释执行为BIGINT,或者使用以下后缀进行说明。

    类型 后缀 例子
    TINYINT Y 100Y
    SMALLINT S 100S
    BIGINT L 100L

    大于BIGINT的数值,需要使用BD后缀以及Decimal(38,0)来处理。

    select CAST(18446744073709001000BD AS DECIMAL(38,0)) from dual limit 1;
    
    

      Hive的小数型是基于Java BigDecimal做的, BigDecimal在java中用于表示任意精度的小数类型。所有常规数字运算(例如+, - ,*,/)和相关的UDFs(例如Floor,Ceil,Round等等)都使用和支持Decimal。你可以将Decimal和其他数值型互相转换,且Decimal支持科学计数法和非科学计数法。因此,无论您的数据集是否包含如4.004E + 3(科学记数法)或4004(非科学记数法)或两者的组合的数据,可以使用Decimal。
      从Hive 0.13开始,用户可以使用DECIMAL(precision, scale) 语法在创建表时来定义Decimal数据类型的precision和scale。 如果未指定precision,则默认为10。如果未指定scale,它将默认为0(无小数位)。

    5) 使用示例

    # 创建员工表:
    create table employees(name string,sex char(10),age int,salary float,address varchar(50));
    OK
    No rows affected (0.682 seconds)
    
    # 创建部门表:
    create table deptarment(id int,deptname string,joindate date,bonus decimal(10,2));
    OK
    No rows affected (0.182 seconds)
    
    

    6) 类型转换函数

    # 创建虚表
    create table dual(dummy string);
    # 必须插入一条记录,否则查不到结果
    insert into dual values('1');
    

    cast() 转换函数
    对于Date类型的数据,只能在Date、Timestamp以及String之间进行转换。下表将进行详细的说明:

    有效的转换 结果
    cast(date as date) 返回date类型
    cast(timestamp as date) timestamp中的年/月/日的值是依赖与当地的时区,结果返回date类型
    cast(string as date) 如果string是YYYY-MM-DD格式的,则相应的年/月/日的date类型的数据将会返回;但如果string不是YYYY-MM-DD格式的,结果则会返回NULL。
    cast(date as timestamp) 基于当地的时区,生成一个对应date的年/月/日的时间戳值
    cast(date as string) date所代表的年/月/日时间将会转换成YYYY-MM-DD的字符串。

    字符串转为float:

    0: jdbc:hive2://192.168.71.130:10000> select cast(salary as float) from employee;
    OK
    +---------+
    | salary  |
    +---------+
    | 100.3   |
    +---------+
    1 row selected (0.307 seconds)
    
    

    7) Null 值

    缺少值通过特殊值 - NULL表示。

    2. 复杂类型

    复杂类型包括ARRAY,MAP,STRUCT,UNION,这些复杂类型是由基础类型组成的。
    ARRAY:ARRAY类型是由一系列相同数据类型的元素组成,这些元素可以通过下标来访问。比如有一个ARRAY类型的变量fruits,它是由['apple','orange','mango']组成,那么我们可以通过fruits[1]来访问元素orange,因为ARRAY类型的下标是从0开始的;
    MAP:MAP包含key->value键值对,可以通过key来访问元素。比如”userlist”是一个map类型,其中username是key,password是value;那么我们可以通过userlist['username']来得到这个用户对应的password;
    STRUCT:STRUCT可以包含不同数据类型的元素。这些元素可以通过”点语法”的方式来得到所需要的元素,比如user是一个STRUCT类型,那么可以通过user.address得到这个用户的地址。
    UNION: UNIONTYPE,他是从Hive 0.7.0开始支持的。

    1). 数组

    在Hive 数组与在Java中使用的方法相同。

    Syntax: ARRAY<data_type>
    

    ARRAY是具有相关同类型和名称的变量的集合['John','Doe'] 如:Array(['John','Doe'] )

    2). 映射

    映射在Hive类似于Java的映射。

    Syntax: MAP<primitive_type, data_type>
    

    MAP是一组键值对集合 字段名[last]获取值 如:map('first','Join','last','Doe')

    3). 结构体

    在Hive结构体类似于使用复杂的数据。

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

    STRUCT列类型为struct{first STRING,last STRING} 如: struct('john','Doe')

    4). 示例

    name --雇员名,salary --雇员薪水,subordinates --下属员工,deductions --五险一金,个税等,address --雇员的住址

    hive> CREATE TABLE employees(name string,salary float,subordinates array<string>,deductions map<string,float>,address struct<street:string,city:string,state:string,zip:int>);
    

    一个雇员表详细信心存储在一张表中,在RDBMS中则可能存在某个字段的信息存储在另外一张表,通过主外键或查询条件进行连接后获取结果。这里就可以通过一些集合数据类型进行处理了。

    三、hive的文件格式

    TEXTFILE //文本,默认值
    SEQUENCEFILE // 二进制序列文件
    RCFILE //列式存储格式文件 Hive0.6以后开始支持
    ORC //列式存储格式文件,比RCFILE有更高的压缩比和读写效率,Hive0.11以后开始支持
    PARQUET //列出存储格式文件,Hive0.13以后开始支持
    

    四、常见问题:

    1. 分区常见问题
      指定location加载不到数据:
      指定了表的location但是select不出来数据,而目录确实存在hdfs上。
      一个分区一个分区的添加,问题出现的原因是表没有添加到分区,,也就是没有注册,因为数据有可能是之前添加好的再创建表。
      检查是否存在分区:
    hive> show partitions 表;  
    

    表指定location的时候,他只是把表的路径指定一个存储位置,原来有的数据他并不知道,之后再添加的数据他知道,就像是注册一下,以前的东西并没有注册,他不知道里面有数据。

    msck repair table 表名;
    

    命令就是把location里面的数据都注册一遍,包括已经注册过的。

    相关文章

      网友评论

        本文标题:Hadoop开发--Hive--DDL

        本文链接:https://www.haomeiwen.com/subject/yuhgwctx.html