欢迎光临散文网 会员登陆 & 注册

大数据离线阶段 06:HQL数据定义语言(DDL)概述

2023-08-24 11:26 作者:程序员四次元ポケット  | 我要投稿

HQL数据定义语言(DDL)概述

DDL语法的作用

数据定义语言 (Data Definition Language, DDL),是SQL语言集中对数据库内部的对象结构进行创建,删除,修改等的操作语言,这些数据库对象包括database(schema)、table、view、index等。核心语法由CREATE、ALTER与DROP三个所组成。DDL并不涉及表内部数据的操作。

在某些上下文中,该术语也称为数据描述语言,因为它描述了数据库表中的字段和记录。


Hive中DDL使用

Hive SQL(HQL)与SQL的语法大同小异,基本上是相通的,学过SQL的使用者可以无痛使用Hive SQL。只不过在学习HQL语法的时候,特别要注意Hive自己特有的语法知识点,比如partition相关的DDL操作。

基于Hive的设计、使用特点,HQL中create语法(尤其create table)将是学习掌握DDL语法的重中之重。可以说建表是否成功直接影响数据文件是否映射成功,进而影响后续是否可以基于SQL分析数据。通俗点说,没有表,表没有数据,你分析什么呢?

选择正确的方向,往往比盲目努力重要。

Hive DDL建表基础

完整建表语法树


  • 蓝色字体是建表语法的关键字,用于指定某些功能。

  • []中括号的语法表示可选。

  • |表示使用的时候,左右语法二选一。

  • 建表语句中的语法顺序要和上述语法规则保持一致。

Hive数据类型详解

整体概述

Hive中的数据类型指的是Hive表中的列字段类型。Hive数据类型整体分为两个类别:原生数据类型(primitive data type)和复杂数据类型(complex data type)。

原生数据类型包括:数值类型、时间类型、字符串类型、杂项数据类型;

复杂数据类型包括:array数组、map映射、struct结构、union联合体。

关于Hive的数据类型,需要注意:

  • 英文字母大小写不敏感;

  • 除SQL数据类型外,还支持Java数据类型,比如:string;

  • int和string是使用最多的,大多数函数都支持;

  • 复杂数据类型的使用通常需要和分隔符指定语法配合使用。

  • 如果定义的数据类型和文件不一致,hive会尝试隐式转换,但是不保证成功。

原生数据类型

Hive支持的原生数据类型如下图所示:

其中标注的数据类型是使用较多的,详细的描述请查询语法手册:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types

复杂数据类型

Hive支持的复杂数据类型如下图所示:

其中标注的数据类型是使用较多的,详细的描述请查询语法手册:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types

数据类型隐式、显示转换

与SQL类似,HQL支持隐式和显式类型转换。

原生类型从窄类型到宽类型的转换称为隐式转换,反之,则不允许。

下表描述了类型之间允许的隐式转换:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types

显式类型转换使用CAST函数。

例如,CAST('100'as INT)会将100字符串转换为100整数值。 如果强制转换失败,例如CAST('INT'as INT),该函数返回NULL。


Hive读写文件机制

SerDe是什么

SerDe是Serializer、Deserializer的简称,目的是用于序列化和反序列化。序列化是对象转化为字节码的过程;而反序列化是字节码转换为对象的过程。

Hive使用SerDe(和FileFormat)读取和写入行对象。

需要注意的是,“key”部分在读取时会被忽略,而在写入时key始终是常数。基本上行对象存储在“value”中。

可以通过desc formatted tablename查看表的相关SerDe信息。默认如下:


Hive读写文件流程

Hive读取文件机制:首先调用InputFormat(默认TextInputFormat),返回一条一条kv键值对记录(默认是一行对应一条记录)。然后调用SerDe(默认LazySimpleSerDe)的Deserializer,将一条记录中的value根据分隔符切分为各个字段。

Hive写文件机制:将Row写入文件时,首先调用SerDe(默认LazySimpleSerDe)的Serializer将对象转换成字节序列,然后调用OutputFormat将数据写入HDFS文件中。

SerDe相关语法

在Hive的建表语句中,和SerDe相关的语法为:

其中ROW FORMAT是语法关键字,DELIMITED和SERDE二选其一。

如果使用delimited表示使用默认的LazySimpleSerDe类来处理数据。如果数据文件格式比较特殊可以使用ROW FORMAT SERDE serde_name指定其他的Serde类来处理数据,甚至支持用户自定义SerDe类。

LazySimpleSerDe分隔符指定

LazySimpleSerDe是Hive默认的序列化类,包含4种子语法,分别用于指定字段之间、集合元素之间、map映射 kv之间、换行的分隔符号。在建表的时候可以根据数据的特点灵活搭配使用。


默认分隔符

hive建表时如果没有row format语法。此时字段之间默认的分割符是'\001',是一种特殊的字符,使用的是ascii编码的值,键盘是打不出来的。

在vim编辑器中,连续按下Ctrl+v/Ctrl+a即可输入'\001' ,显示^A

在一些文本编辑器中将以SOH的形式显示:


Hive数据存储路径

默认存储路径

Hive表默认存储路径是由${HIVE_HOME}/conf/hive-site.xml配置文件的hive.metastore.warehouse.dir属性指定。默认值是:/user/hive/warehouse。

在该路径下,文件将根据所属的库、表,有规律的存储在对应的文件夹下。


指定存储路径

在Hive建表的时候,可以通过location语法来更改数据在HDFS上的存储路径,使得建表加载数据更加灵活方便。

语法:LOCATION '<hdfs_location>'。

对于已经生成好的数据文件,使用location指定路径将会很方便。

案例—王者荣耀

原生数据类型案例

文件archer.txt中记录了手游《王者荣耀》射手的相关信息,内容如下所示,其中字段之间分隔符为制表符\t,要求在Hive中建表映射成功该文件。

字段含义:id、name(英雄名称)、hp_max(最大生命)、mp_max(最大法力)、attack_max(最高物攻)、defense_max(最大物防)、attack_range(攻击范围)、role_main(主要定位)、role_assist(次要定位)。

分析一下:字段都是基本类型,字段的顺序需要注意一下。字段之间的分隔符是制表符,需要使用row format语法进行指定。

建表语句:

建表成功之后,在Hive的默认存储路径下就生成了表对应的文件夹,把archer.txt文件上传到对应的表文件夹下。

执行查询操作,可以看出数据已经映射成功。

想一想:Hive这种能力是不是比mysql一条一条insert插入数据方便多了?

复杂数据类型案例

文件hot_hero_skin_price.txt中记录了手游《王者荣耀》热门英雄的相关皮肤价格信息,内容如下,要求在Hive中建表映射成功该文件。

字段:id、name(英雄名称)、win_rate(胜率)、skin_price(皮肤及价格)

分析一下:前3个字段原生数据类型、最后一个字段复杂类型map。需要指定字段之间分隔符、集合元素之间分隔符、map kv之间分隔符。

建表语句:

建表成功后,把hot_hero_skin_price.txt文件上传到对应的表文件夹下。


执行查询操作,可以看出数据已经映射成功。

想一想:如果最后一个字段以String类型来定义,后续使用方便吗?

默认分隔符案例

文件team_ace_player.txt中记录了手游《王者荣耀》主要战队内最受欢迎的王牌选手信息,内容如下,要求在Hive中建表映射成功该文件。

字段:id、team_name(战队名称)、ace_player_name(王牌选手名字)

分析一下:数据都是原生数据类型,且字段之间分隔符是\001,因此在建表的时候可以省去row format语句,因为hive默认的分隔符就是\001。

建表语句:

建表成功后,把team_ace_player.txt文件上传到对应的表文件夹下。

执行查询操作,可以看出数据已经映射成功。

想一想:字段以\001分隔建表时很方便,那么采集、清洗数据时对数据格式追求有什么启发?你青睐于什么分隔符?

大数据离线阶段 06:HQL数据定义语言(DDL)概述的评论 (共 条)

分享到微博请遵守国家法律