概念

什么是 Hive

Hive 是基于 Apache Hadoop 的数据仓库基础架构。Hadoop 为商用硬件上的数据存储和处理提供了大规模的水平扩展和容错功能。

Hive 旨在简化数据汇总、临时查询和分析大量数据的过程。它提供了 SQL 方言,使用户可以轻松地进行即席查询(Ad-hoc Query)、摘要和数据分析。同时,Hive 的 SQL 为用户提供了多个扩展点,以集成他们自己的功能进行自定义分析,例如用户定义函数(UDF)。

Hive 不是什么

Hive 不适用于在线交易处理(OLTP)。它最佳用于传统数据仓库任务。

入门

有关设置 Hive、HiveServer2 和 Beeline 的详细信息,请参阅 GettingStarted 指南。

有关 Hive 的书籍 列出了一些可能对 Hive 入门也很有帮助的书籍。

在以下各节中,我们提供有关系统功能的教程。我们首先描述数据类型、表和分区的概念(与传统的关系型 DBMS 中的概念非常相似),然后借助一些示例来说明 Hive 的功能。

数据单位

按粒度顺序,Hive 数据组织为:

  • 数据库(Database):命名空间的作用是避免表、视图、分区、列等的命名冲突。数据库还可以用于对一个用户或一组用户强制实施安全性。
  • 表(Table):具有相同架构的同类数据单元。一个表的示例可以是 page_views 表,其中每一行可以包含以下列(模式):

    • timestamp — 属于 INT 类型,与查看该页面的 UNIX 时间戳相对应。
    • userid — 是 BIGINT 类型,用于标识查看该页面的用户。
    • page_url — 属于 STRING 类型,用于捕获页面的位置。
    • referer_url — 属于 STRING 类型,可捕获用户到达当前页面的页面位置。
    • IP — 属于 STRING 类型,用于捕获发出页面请求的 IP 地址。
  • 分区(Partition):每个表可以具有一个或多个分区键,这些键确定数据的存储方式。分区除了作为存储单元外,还允许用户有效地标识满足指定条件的行;例如,类型为 STRINGdate_partition 和类型为 STRINGcountry_partition。分区键的每个唯一值定义表的一个分区。例如,来自"2009-12-23"的所有"US"数据都是 page_views 表的一个分区。因此,如果仅对 2009-12-23 的"US"数据运行分析,则可以仅对表的相关分区运行该查询,从而大大加快了分析速度。但是请注意,仅因为分区名为 2009-12-23 并不意味着该分区包含该日期之后全部或仅该日期的数据。为方便起见,分区以日期命名;保证分区名称和数据内容之间的关系是用户的工作!分区列是虚拟列。
  • 分桶(Bucket)(或 Cluster):每个分区中的数据又可以根据表中某些列的哈希函数的值分为存储桶。例如,page_views 表可以按 userid 进行分桶,useridpage_view 表中除分区列之外的列之一。这些可用于有效采样数据。

请注意,不必对表进行分区或分桶,但是这些抽象使系统可以在查询处理期间修剪大量数据,从而加快查询执行速度。

类型系统

Hive 支持原始和复杂的数据类型,如下所述。有关其他信息,请参见 Hive 数据类型

基本类型

  • 类型与表中的列关联。支持以下基本类型:

    • 整数

      • TINYINT — 1 个字节的整数
      • SMALLINT — 2 字节整数
      • INT — 4 字节整数
      • BIGINT — 8 字节整数
    • 布尔型

      • BOOLEANTRUE / FALSE
    • 浮点数字

      • FLOAT — 单精度
      • DOUBLE — 双精度
    • 定点数

      • DECIMAL — 用户定义的比例和精度的固定点值
    • 字符串类型

      • STRING — 指定字符集中的字符序列
      • VARCHAR — 指定字符集中最大长度的字符序列
      • CHAR — 具有定义长度的指定字符集中的字符序列
    • 日期和时间类型

      • TIMESTAMP — 不带时区的日期和时间("LocalDateTime"语义)
      • TIMESTAMP WITH LOCAL TIME ZONE — 精确到纳秒的时间点("Instant"语义)
      • DATE — 日期
    • 二进制类型

      • BINARY — 字节序列

这些类型按以下层次结构进行组织(其中父级是所有子级实例的超类型):

image.png

此类型层次结构定义如何在查询语言中隐式转换类型。允许从子类型到祖先类型的隐式转换。因此,当查询表达式期望类型为 1 且数据类型为 2 时,如果类型 1 是类型层次结构中类型 2 的祖先,则类型 2 将隐式转换为类型 1。请注意,类型层次结构允许将 STRING 隐式转换为 DOUBLE

可以使用 强制 转换运算符来进行显式类型转换,如下面的"内置函数"部分所示。

复杂类型

可以使用以下方法从原始类型和其他组合类型中构建复杂类型:

  • 结构体(STRUCT):可以使用点(.)表示法访问类型内的元素。例如,对于类型 STRUCT {a INT; b INT},则表达式 c.a 访问 a 字段。
  • 映射(MAP)(键值元组):使用 ['element name'] 表示法访问元素。例如,在包含从 'group' -> gid 的映射组成的映射 M 中,可以使用 M['group'] 访问 gid 值。
  • 数组(ARRAY)(可索引列表):数组中的元素必须具有相同的类型。可以使用 [n] 表示法访问元素,其中 n 是数组的索引(从零开始)。例如,对于具有元素 ['a', 'b', 'c'] 的数组 AA[1] 返回 'b'

使用原始类型和用于创建复杂类型的构造,可以创建具有任意嵌套级别的类型。例如,用户类型可以包含以下字段:

  • gender — 这是 STRING
  • active — 这是 BOOLEAN

时间戳

时间戳概念常引起混淆,因此我们尝试记录 Hive 的预期语义。

时间戳("LocalDateTime"语义)

Java 的"LocalDateTime"时间戳将日期和时间记录为年、月、日、时、分和秒,没有时区。无论本地时区如何,这些时间戳始终具有相同的值。

例如,时间戳值"2014-12-12 12:34:56"被分解为年、月、日、小时、分钟和秒字段,但是没有可用的时区信息。它不对应于任何特定时刻。无论本地时区如何,它将始终是相同的值。除非您的应用程序始终使用 UTC,否则对于大多数应用程序,时间戳优先于本地时区。当用户说某个事件是在 10:00 时,它始终是相对于某个时区的,它表示一个时间点,而不是任意时区中的 10:00。

具有本地时区的时间戳("Instant"语义)

Java 的"Instant"时间戳定义了一个恒定的时间点,无论从何处读取数据。因此,时间戳将通过本地时区进行调整以匹配原始时间点。

TypeValue in America/Los_AngelesValue in America/New_York
timestamp2014-12-12 12:34:562014-12-12 12:34:56
timestamp with local time zone2014-12-12 12:34:562014-12-12 15:34:56

与其他工具的比较

SQL 2003OracleSybasePostgresMySQLMicrosoft SQLIBM DB2PrestoSnowflakeHive >= 3.1IcebergSpark
timestampLocalLocalLocalLocalInstantOtherLocalLocalLocalLocalLocalInstant
timestamp with local time zone Instant InstantInstant
timestamp with time zoneOffsetOffsetOffsetInstant OffsetOffsetOffset Instant
timestamp without time zoneLocalLocal Local Local

其他定义:

  • Offset = 记录时间点以及编写者所在时区中的时区偏移量。

内置的运算符和功能

下面列出的运算符和功能不一定是最新的。(Hive Operators 和 UDF 具有更多当前信息。)在 Beeline 或 Hive CLI 中,使用以下命令显示最新文档:

SHOW FUNCTIONS;
DESCRIBE FUNCTION <function_name>;
DESCRIBE FUNCTION EXTENDED <function_name>;

不区分大小写

所有 Hive 关键字都不区分大小写,包括 Hive 运算符和函数的名称。

内置运算符

  • 关系运算符 — 以下运算符比较传递的操作数并生成 TRUEFALSE 值,具体取决于操作数之间的比较是否成立。
关系运算符操作数类型描述
A = B所有原始类型如果表达式 A 等于表达式 B,则为 TRUE;否则为 FALSE
A != B所有原始类型如果表达式 A 不等于表达式 B,则为 TRUE;否则为 FALSE
A < B所有原始类型如果表达式 A 小于表达式 B,则为 TRUE;否则为 FALSE
A <= B所有原始类型如果表达式 A 小于或等于表达式 B,则为 TRUE;否则为 FALSE
A > B所有原始类型如果表达式 A 大于表达式 B,则为 TRUE;否则为 FALSE
A >= B所有原始类型如果表达式 A 大于或等于表达式 B,则为 TRUE;否则为 FALSE
A IS NULL所有类型如果表达式 A 的计算结果为 NULL,则为 TRUE,否则为 FALSE
A IS NOT NULL所有类型如果表达式 A 的计算结果为 NULL,则为 FALSE,否则为 TRUE
A LIKE Bstrings如果字符串 A 与 SQL 简单正则表达式 B 匹配,则为 TRUE,否则为 FALSE。逐个字符进行比较。在 B 中的 _ 字符与所述的任何字符(类似于 . 在 POSIX 正则表达式),和 B 中的 % 字符的字符中所述的任意数量的匹配(相似 * 在 POSIX 正则表达式)。例如,'foobar' LIKE 'foo'FALSE 求值,'foobar' LIKE 'foo___'TRUE 求值,'foobar' LIKE 'foo%'TRUE 求值。要转义 %,请使用 \\% 匹配一个 % 字符)。如果数据包含分号,并且您要搜索,则需要转义,columnValue LIKE 'a\;b'
A RLIKE Bstrings如果 A 或 B 为 NULL,则为 NULL,如果 A 的任何子字符串(可能为空)与 Java 正则表达式 B 匹配(请参见 Java 正则表达式语法),则为 TRUE,否则为 FALSE。例如,'foobar' rlike 'foo' 的计算结果为 TRUE'foobar' rlike '^f.*r$' 的计算结果也为 TRUE
A REGEXP BstringsRLIKE 相同
  • 算术运算符 — 以下运算符支持对操作数的各种常见算术运算。它们都返回数字类型。
算术运算符操作数类型描述
A + B所有数字类型给出将 A 和 B 相加的结果。结果的类型与操作数类型的公共父级(在类型层次结构中)相同,例如,因为每个整数都是浮点数。因此,float 是整数的包含类型,因此 floatint 上的 + 运算符将导致 float
A - B所有数字类型给出从 A 减去 B 的结果。结果的类型与操作数类型的公共父级(在类型层次结构中)相同。
A * B所有数字类型给出将 A 和 B 相乘的结果。结果的类型与操作数类型的公共父级(在类型层次结构中)相同。请注意,如果乘法导致溢出,则必须将其中一个运算符转换为类型层次结构中较高的类型。
A / B所有数字类型给出从 A 除以 B 的结果。结果的类型与操作数类型的公共父级(在类型层次结构中)相同。如果操作数是整数类型,则结果是除法的商。
A % B所有数字类型给出 A 除以 B 的余数。结果的类型与操作数类型的公共父级(在类型层次结构中)相同。
A & B所有数字类型给出 A 和 B 的按位与的结果。结果的类型与操作数类型的公共父级(在类型层次结构中)相同。
`A \B`所有数字类型给出 A 和 B 的按位或的结果。结果的类型与操作数类型的公共父级(在类型层次结构中)相同。
A ^ B所有数字类型给出 A 和 B 的按位 XOR 结果。结果的类型与操作数类型的公共父级(在类型层次结构中)相同。
~ A所有数字类型给出 A 的按位 NOT 的结果。结果的类型与 A 的类型相同。
  • 逻辑运算符 — 以下运算符为创建逻辑表达式提供支持。它们都根据操作数的布尔值返回布尔值 TRUEFALSE
逻辑运算符操作数类型描述
A AND B布尔值如果 A 和 B 均为 TRUE,则为 TRUE,否则为 FALSE
A && B布尔值A AND B 相同
A OR B布尔值如果 A 或 B 或两者均为 TRUE,则为 TRUE,否则为 FALSE
`A \\B`布尔值A OR B 相同
NOT A布尔值如果 A 为 FALSE,则为 TRUE,否则为 FALSE
! A布尔值NOT A 相同
  • 复杂类型上的运算符 — 以下运算符提供了访问复杂类型上的元素的机制
运算符操作数类型描述
A[n]A 是一个数组,n 是一个整数返回数组 A 中的第 n 个元素。第一个元素的索引为 0,例如,如果 A 是包含 ['foo', 'bar'] 的数组,则 A[0] 返回 'foo',而 A[1] 返回 'bar'
M[key]M 是 Map<K,V> 并且键的类型为 K例如,如果 M 是包含 {'f'->'foo', 'b'->'bar', 'all'->'foobar'} 的映射,则 M['all'] 返回 'foobar'
S.xS 是一个结构返回 S 的 x 字段,例如,对于 struct foobar {int foo, int bar}foobar.foo 返回存储在 struct 的 foo 字段中的整数。

内置功能

返回类型函数名称 (签名)描述
BIGINTround(double a)返回 double 的四舍五入 BIGINT 值
BIGINTfloor(double a)返回小于或等于该 double 的最大 BIGINT 值
BIGINTceil(double a)返回大于或等于该 double 的最小 BIGINT 值
doublerand(), rand(int seed)返回一个随机数(随行变化)。指定种子将确保生成的随机数序列是确定的。
stringconcat(string A, string B, ...)返回将 B 连接在 A 之后形成的字符串。例如,concat('foo', 'bar') 结果为 'foobar'。此函数接受任意数量的参数并返回它们的连接。
stringsubstr(string A, int start)返回从 start 位置开始到字符串 A 末尾的子字符串。例如,substr('foobar', 4) 结果为 'bar'
stringsubstr(string A, int start, int length)返回从 start 位置开始具有给定长度的 A 的子字符串,例如,substr('foobar', 4, 2) 结果为 'ba'
stringupper(string A)返回将 A 的所有字符转换为大写后形成的字符串,例如,upper('fOoBaR') 结果为 'FOOBAR'
stringucase(string A)upper 相同
stringlower(string A)返回将 A 的所有字符转换为小写后形成的字符串,例如,lower('fOoBaR') 结果为 'foobar'
stringlcase(string A)lower 相同
stringtrim(string A)返回从 A 两端修剪空格后形成的字符串,例如,trim(' foobar ') 结果为 'foobar'
stringltrim(string A)返回从 A 开头(左侧)修剪空格后形成的字符串。例如,ltrim(' foobar ') 结果为 'foobar '
stringrtrim(string A)返回从 A 结尾(右侧)修剪空格后形成的字符串。例如,rtrim(' foobar ') 结果为 ' foobar'
stringregexp_replace(string A, string B, string C)返回将 B 中所有匹配 Java 正则表达式语法(参见 Java 正则表达式语法)的子字符串替换为 C 后形成的字符串。例如,`regexp_replace('foobar', 'oo\ar', '') 返回 'fb'`
intsize(Map<K,V>)返回 map 类型中的元素数量
intsize(Array<T>)返回 array 类型中的元素数量
value of <type>cast(<expr> as <type>)将表达式 expr 的结果转换为 <type>,例如,cast('1' as BIGINT) 将字符串 '1' 转换为其整数表示。如果转换不成功,则返回 null。
stringfrom_unixtime(int unixtime)将 UNIX 纪元(1970-01-01 00:00:00 UTC)以来的秒数转换为表示当前系统时区中该时刻的时间戳字符串,格式为"1970-01-01 00:00:00"
stringto_date(string timestamp)返回时间戳字符串的日期部分:to_date("1970-01-01 00:00:00") = "1970-01-01"
intyear(string date)返回日期或时间戳字符串的年份部分:year("1970-01-01 00:00:00") = 1970, year("1970-01-01") = 1970
intmonth(string date)返回日期或时间戳字符串的月份部分:month("1970-11-01 00:00:00") = 11, month("1970-11-01") = 11
intday(string date)返回日期或时间戳字符串的日期部分:day("1970-11-01 00:00:00") = 1, day("1970-11-01") = 1
stringget_json_object(string json_string, string path)根据指定的 json 路径从 json 字符串中提取 json 对象,并返回提取的 json 对象的 json 字符串。如果输入 json 字符串无效,它将返回 null。

语言能力

Hive 的 SQL 提供了基本的 SQL 操作。这些操作适用于表或分区。这些操作包括:

  • 能够使用 WHERE 子句从表中过滤行。
  • 可以使用 SELECT 子句从表中选择某些列。
  • 在两个表之间进行等值联接的能力。
  • 能够针对表中存储的数据评估多个 GROUP BY 列上的聚合。
  • 能够将查询结果存储到另一个表中。
  • 能够将表的内容下载到本地(例如,nfs)目录。
  • 能够将查询结果存储在 Hadoop DFS 目录中。
  • 能够管理表和分区(创建、删除和更改)。
  • 能够以自定义 Map/Reduce 作业选择的语言插入自定义脚本。

用法与范例

注意:以下许多示例已过时。在 LanguageManual 中 可以找到更多最新信息。

以下示例突出了系统的一些显著功能。详细的查询测试用例集可以在 Hive 查询测试用例中 找到,相应的结果可以在 查询测试用例结果中找到

创建、显示、更改和删除表

有关创建、显示、更改和删除表的详细信息,请参见 Hive 数据定义语言

建立表格

创建上面提到的 page_view 表的示例语句如下所示:

CREATE TABLE page_view(viewTime INT, userid BIGINT,
                       page_url STRING, referrer_url STRING,
                       ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
STORED AS SEQUENCEFILE;

在此示例中,使用相应的类型指定表的列。注释可以附加在列级和表级。此外,PARTITIONED BY 子句定义的分区列与数据列不同,实际上并未与数据一起存储。以这种方式指定时,假定文件中的数据使用 ASCII 001(ctrl-A)作为字段定界符,使用换行符作为行定界符来定界。

如果数据不是上述格式的数据,则可以对字段定界符进行参数设置,如下例所示:

CREATE TABLE page_view(viewTime INT, userid BIGINT,
                       page_url STRING, referrer_url STRING,
                       ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '1'
STORED AS SEQUENCEFILE;

由于行分隔符不是由 Hive 而是由 Hadoop 分隔符确定,因此当前无法更改行分隔符。

将表存储在某些列上也是一个好主意,以便可以针对数据集执行有效的采样查询。如果没有存储分区,仍然可以在表上进行随机采样,但是效率不高,因为查询必须扫描所有数据。以下示例说明了在 userid 列上分桶的 page_view 表的情况:

CREATE TABLE page_view(viewTime INT, userid BIGINT,
                       page_url STRING, referrer_url STRING,
                       ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '1'
    COLLECTION ITEMS TERMINATED BY '2'
    MAP KEYS TERMINATED BY '3'
STORED AS SEQUENCEFILE;

在上面的示例中,该表通过 userid 的哈希函数聚集到 32 个存储桶中。在每个存储桶中,数据按 viewTime 的升序排序。这样的组织允许用户在聚集列上进行高效采样——在这种情况下为用户 ID。排序属性允许内部运算符在更好地评估查询的同时利用众所周知的数据结构。

CREATE TABLE page_view(viewTime INT, userid BIGINT,
                       page_url STRING, referrer_url STRING,
                       friends ARRAY<BIGINT>, properties MAP<STRING, STRING>
                       ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY '1'
    COLLECTION ITEMS TERMINATED BY '2'
    MAP KEYS TERMINATED BY '3'
STORED AS SEQUENCEFILE;

在此示例中,以与类型定义类似的方式指定组成表行的列。注释可以附加在列级和表级。此外,PARTITIONED BY 子句定义的分区列与数据列不同,实际上并未与数据一起存储。CLUSTERED BY 子句指定用于分桶的列以及要创建的桶数。分隔行格式指定行如何在 Hive 表中存储。在定界格式的情况下,这指定了字段的终止方式,集合(数组或映射)中的项目的终止方式以及映射键的终止方式。STORED AS SEQUENCEFILE 表示此数据以二进制格式(使用 Hadoop SequenceFiles)存储在 HDFS 上。

表名和列名不区分大小写。

浏览表和分区

SHOW TABLES;

列出仓库中的现有表;其中有很多,可能比您想要浏览的更多。

SHOW TABLES 'page.*';

列出前缀为"page"的表。该模式遵循 Java 正则表达式语法(因此句点是通配符)。

SHOW PARTITIONS page_view;

列出表分区。如果该表不是分区表,则将引发错误。

DESCRIBE page_view;

列出表的列和列类型。

DESCRIBE EXTENDED page_view;

列出表的列和所有其他属性。这会打印很多信息,但也不会以漂亮的格式显示。通常用于调试。

DESCRIBE EXTENDED page_view PARTITION (ds='2008-08-08');

列出分区的列和所有其他属性。这还会打印很多通常用于调试的信息。

修改表

将现有表重命名为新名称。如果具有新名称的表已经存在,则返回错误:

ALTER TABLE old_table_name RENAME TO new_table_name;

重命名现有表的列。确保使用相同的列类型,并为每个现有列包括一个条目:

ALTER TABLE old_table_name REPLACE COLUMNS (col1 TYPE, ...);

要将列添加到现有表:

ALTER TABLE tab1 ADD COLUMNS (c1 INT COMMENT 'a new int column', c2 STRING DEFAULT 'def val');

请注意,架构的更改(例如添加列)会在表是分区表的情况下保留表的旧分区的架构。所有访问这些列并在旧分区上运行的查询都隐式地为这些列返回空值或指定的默认值。

在以后的版本中,我们可以使假设某些值的行为与在特定分区中未找到该列的情况下抛出错误相反。

删除表和分区

删除表相当简单。将该表放下将隐式删除该表上已建立的所有索引(这是将来的功能)。关联的命令是:

DROP TABLE pv_users;

删除分区。更改表以删除分区。

ALTER TABLE pv_users DROP PARTITION (ds='2008-08-08')
  • 请注意,此表或分区的任何数据将被删除并且可能无法恢复。

加载数据

有多种方法可以将数据加载到 Hive 表中。用户可以创建一个指向 HDFS 中 指定位置的外部表。在这种特定用法中,用户可以使用 HDFS 放置或复制命令将文件复制到指定位置,并创建一个指向该位置的表以及所有相关的行格式信息。完成此操作后,用户可以转换数据并将其插入任何其他 Hive 表中。例如,如果文件 /tmp/pv_2008-06-08.txt 包含 2008 年 6 月 8 日提供的用逗号分隔的页面视图,并且需要将其加载到适当分区中的 page_view 表中,则可以按照以下命令顺序进行操作实现这一目标:

CREATE EXTERNAL TABLE page_view_stg(viewTime INT, userid BIGINT,
                       page_url STRING, referrer_url STRING,
                       ip STRING COMMENT 'IP Address of the User',
                       country STRING COMMENT 'country of origination')
COMMENT 'This is the staging page view table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '44' LINES TERMINATED BY '12'
STORED AS TEXTFILE
LOCATION '/user/data/staging/page_view';

hadoop dfs -put /tmp/pv_2008-06-08.txt /user/data/staging/page_view

FROM page_view_stg pvs
INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='US')
SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip
WHERE pvs.country = 'US';
  • 由于 LINES TERMINATED BY 限制,此代码导致错误

    • 失败:SemanticException 6:67 终止符行现在仅支持换行符 '\n'。令牌"12"附近遇到错误
    • 参见 HIVE-5999 - 允许其他字符 TERMINATED 由线 打开
    • HIVE-11996 - 行分隔符不是 '\n' 其他抛出 Hive 错误。打开

在上面的示例中,在目标表中为数组和映射类型插入了空值,但如果指定了正确的行格式,则它们也可能来自外部表。

如果 HDFS 中已经存在旧数据,用户想要在其中放置一些元数据,以便可以使用 Hive 查询和操作该数据,则此方法很有用。

此外,系统还支持语法,可以将本地文件系统中文件中的数据直接加载到 Hive 表中,其中输入数据格式与表格式相同。如果 /tmp/pv_2008-06-08_us.txt 已经包含美国的数据,则我们不需要任何其他过滤,如上例所示。在这种情况下,可以使用以下语法完成加载:

LOAD DATA LOCAL INPATH '/tmp/pv_2008-06-08_us.txt' INTO TABLE page_view PARTITION(date='2008-06-08', country='US')

path 参数可以使用目录(在这种情况下,将加载目录中的所有文件),单个文件名或通配符(在这种情况下,将所有匹配的文件上载)。如果参数是一个目录,则它不能包含子目录。同样,通配符必须仅与文件名匹配。

如果输入文件 /tmp/pv_2008-06-08_us.txt 非常大,则用户可以决定对数据进行并行加载(使用 Hive 外部的工具)。将文件放入 HDFS 后,可以使用以下语法将数据加载到 Hive 表中:

LOAD DATA INPATH '/user/data/pv_2008-06-08_us.txt' INTO TABLE page_view PARTITION(date='2008-06-08', country='US')

对于这些示例,假设 input.txt 文件中的 array 和 map 字段为空字段。

有关将数据加载到 Hive 表中的更多信息,请参见 Hive 数据操作语言;有关创建 外部表 的另一个示例,请参见外部表。

查询和插入数据