- Apache Pig 教程
- Apache Pig - 主页
- Apache Pig介绍
- Apache Pig - 概述
- Apache Pig - 架构
- Apache Pig 环境
- Apache Pig - 安装
- Apache Pig - 执行
- Apache Pig - Grunt Shell
- 猪拉丁语
- 猪拉丁语 - 基础知识
- 加载和存储操作符
- Apache Pig - 读取数据
- Apache Pig - 存储数据
- Pig Latin 内置函数
- Apache Pig - 评估函数
- 加载和存储功能
- Apache Pig - 袋和元组函数
- Apache Pig - 字符串函数
- Apache Pig - 日期时间函数
- Apache Pig - 数学函数
- Apache Pig 有用资源
- Apache Pig - 快速指南
- Apache Pig - 有用的资源
- Apache Pig - 讨论
Apache Pig - 快速指南
Apache Pig - 概述
什么是Apache Pig?
Apache Pig 是 MapReduce 的抽象。它是一个工具/平台,用于分析将其表示为数据流的较大数据集。Pig一般与Hadoop一起使用;我们可以使用 Apache Pig 执行 Hadoop 中的所有数据操作操作。
为了编写数据分析程序,Pig 提供了一种称为Pig Latin的高级语言。该语言提供了各种运算符,程序员可以使用这些运算符开发自己的读取、写入和处理数据的函数。
要使用Apache Pig分析数据,程序员需要使用 Pig Latin 语言编写脚本。所有这些脚本都在内部转换为Map 和Reduce 任务。Apache Pig 有一个称为Pig Engine 的组件,它接受 Pig Latin 脚本作为输入并将这些脚本转换为 MapReduce 作业。
为什么我们需要 Apache Pig?
不太擅长 Java 的程序员通常很难使用 Hadoop,尤其是在执行任何 MapReduce 任务时。Apache Pig 是所有此类程序员的福音。
使用Pig Latin,程序员可以轻松执行 MapReduce 任务,而无需在 Java 中键入复杂的代码。
Apache Pig采用多查询的方式,从而减少了代码的长度。例如,在 Java 中需要键入 200 行代码 (LoC) 的操作只需在 Apache Pig 中键入 10 行代码即可轻松完成。最终,Apache Pig 将开发时间缩短了近 16 倍。
Pig Latin 是一种类似 SQL 的语言,当您熟悉 SQL 时,学习 Apache Pig 就很容易。
Apache Pig 提供了许多内置运算符来支持连接、过滤器、排序等数据操作。此外,它还提供 MapReduce 中缺少的嵌套数据类型,例如元组、包和映射。
猪的特点
Apache Pig 具有以下功能 -
丰富的运算符集- 它提供了许多运算符来执行连接、排序、文件管理器等操作。
易于编程- Pig Latin 与 SQL 类似,如果您擅长 SQL,则很容易编写 Pig 脚本。
优化机会- Apache Pig 中的任务自动优化其执行,因此程序员只需关注语言的语义。
可扩展性- 使用现有的运算符,用户可以开发自己的函数来读取、处理和写入数据。
UDF - Pig 提供了用其他编程语言(例如 Java)创建用户定义函数并在 Pig 脚本中调用或嵌入它们的工具。
处理各种数据- Apache Pig 分析各种数据,包括结构化数据和非结构化数据。它将结果存储在 HDFS 中。
Apache Pig 与 MapReduce
下面列出了 Apache Pig 和 MapReduce 之间的主要区别。
Apache Pig | 映射减少 |
---|---|
Apache Pig 是一种数据流语言。 | MapReduce 是一种数据处理范例。 |
它是一种高级语言。 | MapReduce 是低级且僵化的。 |
在 Apache Pig 中执行 Join 操作非常简单。 | 在MapReduce中执行数据集之间的Join操作是相当困难的。 |
任何具有 SQL 基本知识的新手程序员都可以轻松地使用 Apache Pig。 | 要使用 MapReduce,必须接触 Java。 |
Apache Pig采用多查询的方式,从而很大程度上减少了代码的长度。 | MapReduce 执行相同任务将需要几乎 20 倍的行数。 |
不需要编译。在执行时,每个 Apache Pig 运算符都会在内部转换为 MapReduce 作业。 | MapReduce作业有一个漫长的编译过程。 |
Apache Pig 与 SQL
下面列出了 Apache Pig 和 SQL 之间的主要区别。
猪 | SQL |
---|---|
Pig Latin 是一种过程语言。 | SQL 是一种声明性语言。 |
在 Apache Pig 中,模式是可选的。我们可以在不设计模式的情况下存储数据(值存储为 $01、$02 等) | 模式在 SQL 中是必需的。 |
Apache Pig 中的数据模型是嵌套关系型的。 | SQL 中使用的数据模型是平面关系型的。 |
Apache Pig 为查询优化提供了有限的机会。 | SQL 中有更多查询优化的机会。 |
除了上述差异之外,Apache Pig Latin -
- 允许管道分裂。
- 允许开发人员将数据存储在管道中的任何位置。
- 宣布执行计划。
- 提供操作符来执行ETL(提取、转换和加载)功能。
Apache Pig与蜂巢
Apache Pig 和 Hive 都用于创建 MapReduce 作业。在某些情况下,Hive 在 HDFS 上的运行方式与 Apache Pig 类似。在下表中,我们列出了 Apache Pig 与 Hive 不同的几个重要点。
Apache Pig | 蜂巢 |
---|---|
Apache Pig 使用一种称为Pig Latin的语言。它最初是在雅虎创建的。 | Hive 使用一种称为HiveQL的语言。它最初是在Facebook创建的。 |
Pig Latin 是一种数据流语言。 | HiveQL 是一种查询处理语言。 |
Pig Latin 是一种过程语言,它适合管道范式。 | HiveQL 是一种声明性语言。 |
Apache Pig 可以处理结构化、非结构化和半结构化数据。 | Hive 主要用于结构化数据。 |
Apache Pig 的应用
Apache Pig 通常被数据科学家用来执行涉及临时处理和快速原型设计的任务。使用 Apache Pig -
- 处理网络日志等海量数据源。
- 为搜索平台执行数据处理。
- 处理时间敏感的数据负载。
Apache Pig——历史
2006 年,Apache Pig 被开发为雅虎的一个研究项目,特别是在每个数据集上创建和执行 MapReduce 作业。2007年,Apache Pig通过Apache孵化器开源。2008年,Apache Pig的第一个版本问世。2010年,Apache Pig作为Apache顶级项目毕业。
Apache Pig - 架构
使用 Pig 来分析 Hadoop 中的数据的语言称为Pig Latin。它是一种高级数据处理语言,提供丰富的数据类型和运算符来对数据执行各种操作。
要使用 Pig 执行特定任务,程序员需要使用 Pig Latin 语言编写 Pig 脚本,并使用任何执行机制(Grunt Shell、UDF、嵌入式)执行它们。执行后,这些脚本将经过 Pig 框架应用的一系列转换,以产生所需的输出。
在内部,Apache Pig 将这些脚本转换为一系列 MapReduce 作业,从而使程序员的工作变得轻松。Apache Pig的架构如下图所示。
Apache Pig 组件
如图所示,Apache Pig框架中有各种组件。让我们看一下主要组件。
解析器
最初,Pig 脚本由解析器处理。它检查脚本的语法、类型检查和其他杂项检查。解析器的输出将是一个 DAG(有向无环图),它表示 Pig Latin 语句和逻辑运算符。
在 DAG 中,脚本的逻辑运算符表示为节点,数据流表示为边。
优化器
逻辑计划(DAG)被传递到逻辑优化器,逻辑优化器执行投影和下推等逻辑优化。
编译器
编译器将优化后的逻辑计划编译成一系列MapReduce作业。
执行引擎
最后,MapReduce 作业按排序顺序提交到 Hadoop。最后,这些 MapReduce 作业在 Hadoop 上执行,产生所需的结果。
Pig Latin 数据模型
Pig Latin 的数据模型是完全嵌套的,它允许复杂的非Atomics数据类型,例如map和tuple。下面给出的是 Pig Latin 数据模型的图示。
Atomics
Pig Latin 中的任何单个值,无论其数据和类型如何,都称为Atom。它存储为字符串,可以用作字符串和数字。int、long、float、double、chararray 和 bytearray 是 Pig 的Atomics值。一段数据或一个简单的Atomics值称为字段。
示例- 'raja' 或 '30'
元组
由一组有序字段组成的记录称为元组,字段可以是任何类型。元组类似于 RDBMS 表中的一行。
示例- (Raja, 30)
包
包是一组无序的元组。换句话说,元组(非唯一)的集合称为包。每个元组可以有任意数量的字段(灵活的模式)。包由“{}”表示。它类似于RDBMS中的表,但与RDBMS中的表不同的是,每个元组不必包含相同数量的字段或同一位置(列)的字段具有相同的类型。
示例- {(Raja, 30), (Mohammad, 45)}
包可以是关系中的一个字段;在这种情况下,它被称为内袋。
示例- {Raja, 30, {9848022338, raja@gmail.com,} }
地图
映射(或数据映射)是一组键值对。键必须是 chararray 类型并且应该是唯一的。该值可以是任何类型。用'[]'表示
示例- [姓名#Raja,年龄#30]
关系
关系是一袋元组。Pig Latin 中的关系是无序的(不能保证元组按任何特定顺序处理)。
Apache Pig - 安装
本章介绍如何在系统中下载、安装和设置Apache Pig 。
先决条件
在使用 Apache Pig 之前,您必须在系统上安装 Hadoop 和 Java。因此,在安装 Apache Pig 之前,请按照以下链接中给出的步骤安装 Hadoop 和 Java -
https://www.tutorialspoint.com/hadoop/hadoop_enviornment_setup.htm
下载Apache Pig
首先,从以下网站下载最新版本的 Apache Pig - https://pig.apache.org/
步骤1
打开 Apache Pig 网站的主页。在“新闻”部分下,单击链接发布页面,如下图所示。
第2步
单击指定的链接后,您将被重定向到Apache Pig 版本页面。在此页面的“下载”部分下,您将有两个链接,即Pig 0.8 及更高版本和Pig 0.7 及之前版本。单击链接Pig 0.8 及更高版本,然后您将被重定向到具有一组镜像的页面。
步骤3
选择并单击这些镜像中的任意一个,如下所示。
步骤4
这些镜像将带您进入Pig Releases页面。此页面包含 Apache Pig 的各种版本。单击其中的最新版本。
步骤5
在这些文件夹中,您将拥有各种发行版中 Apache Pig 的源文件和二进制文件。下载Apache Pig 0.15、 pig0.15.0-src.tar.gz和pig-0.15.0.tar.gz的源文件和二进制文件的tar文件。
安装 Apache Pig
下载 Apache Pig 软件后,请按照以下步骤将其安装在 Linux 环境中。
步骤1
在Hadoop、Java等软件的安装目录同一目录下创建一个名为Pig的目录。(在我们的教程中,我们在名为 Hadoop 的用户中创建了 Pig 目录)。
$ mkdir Pig
第2步
解压缩下载的 tar 文件,如下所示。
$ cd Downloads/ $ tar zxvf pig-0.15.0-src.tar.gz $ tar zxvf pig-0.15.0.tar.gz
步骤3
将pig-0.15.0-src.tar.gz文件的内容移动到之前创建的Pig目录中,如下所示。
$ mv pig-0.15.0-src.tar.gz/* /home/Hadoop/Pig/
配置 Apache Pig
安装完 Apache Pig 后,我们必须对其进行配置。要配置,我们需要编辑两个文件 - bashrc 和 pig.properties。
.bashrc 文件
在.bashrc文件中,设置以下变量 -
PIG_HOME文件夹复制到 Apache Pig 的安装文件夹,
bin 文件夹的PATH环境变量,以及
PIG_CLASSPATH环境变量添加到 Hadoop 安装的 etc(配置)文件夹(包含 core-site.xml、hdfs-site.xml 和 mapred-site.xml 文件的目录)。
export PIG_HOME = /home/Hadoop/Pig export PATH = $PATH:/home/Hadoop/pig/bin export PIG_CLASSPATH = $HADOOP_HOME/conf
pig.properties 文件
在Pig 的conf文件夹中,我们有一个名为pig.properties的文件。在pig.properties 文件中,您可以设置各种参数,如下所示。
pig -h properties
支持以下属性 -
Logging: verbose = true|false; default is false. This property is the same as -v switch brief=true|false; default is false. This property is the same as -b switch debug=OFF|ERROR|WARN|INFO|DEBUG; default is INFO. This property is the same as -d switch aggregate.warning = true|false; default is true. If true, prints count of warnings of each type rather than logging each warning. Performance tuning: pig.cachedbag.memusage=<mem fraction>; default is 0.2 (20% of all memory). Note that this memory is shared across all large bags used by the application. pig.skewedjoin.reduce.memusagea=<mem fraction>; default is 0.3 (30% of all memory). Specifies the fraction of heap available for the reducer to perform the join. pig.exec.nocombiner = true|false; default is false. Only disable combiner as a temporary workaround for problems. opt.multiquery = true|false; multiquery is on by default. Only disable multiquery as a temporary workaround for problems. opt.fetch=true|false; fetch is on by default. Scripts containing Filter, Foreach, Limit, Stream, and Union can be dumped without MR jobs. pig.tmpfilecompression = true|false; compression is off by default. Determines whether output of intermediate jobs is compressed. pig.tmpfilecompression.codec = lzo|gzip; default is gzip. Used in conjunction with pig.tmpfilecompression. Defines compression type. pig.noSplitCombination = true|false. Split combination is on by default. Determines if multiple small files are combined into a single map. pig.exec.mapPartAgg = true|false. Default is false. Determines if partial aggregation is done within map phase, before records are sent to combiner. pig.exec.mapPartAgg.minReduction=<min aggregation factor>. Default is 10. If the in-map partial aggregation does not reduce the output num records by this factor, it gets disabled. Miscellaneous: exectype = mapreduce|tez|local; default is mapreduce. This property is the same as -x switch pig.additional.jars.uris=<comma seperated list of jars>. Used in place of register command. udf.import.list=<comma seperated list of imports>. Used to avoid package names in UDF. stop.on.failure = true|false; default is false. Set to true to terminate on the first error. pig.datetime.default.tz=<UTC time offset>. e.g. +08:00. Default is the default timezone of the host. Determines the timezone used to handle datetime datatype and UDFs. Additionally, any Hadoop property can be specified.
验证安装
通过键入 version 命令来验证 Apache Pig 的安装。如果安装成功,您将获得如下所示的 Apache Pig 版本。
$ pig –version Apache Pig version 0.15.0 (r1682971) compiled Jun 01 2015, 11:44:35
Apache Pig - 执行
在上一章中,我们解释了如何安装 Apache Pig。在本章中,我们将讨论如何执行 Apache Pig。
Apache Pig 执行模式
Apache Pig 可以以两种模式运行,即本地模式和HDFS 模式。
本地模式
在此模式下,所有文件都从本地主机和本地文件系统安装并运行。不需要 Hadoop 或 HDFS。该模式一般用于测试目的。
映射缩减模式
MapReduce 模式是我们使用 Apache Pig 加载或处理 Hadoop 文件系统 (HDFS) 中存在的数据的地方。在这种模式下,每当我们执行 Pig Latin 语句来处理数据时,都会在后端调用 MapReduce 作业,对 HDFS 中存在的数据执行特定操作。
Apache Pig 执行机制
Apache Pig脚本可以通过三种方式执行,即交互模式、批处理模式和嵌入模式。
交互模式(Grunt shell)- 您可以使用 Grunt shell 以交互模式运行 Apache Pig。在此 shell 中,您可以输入 Pig Latin 语句并获取输出(使用 Dump 运算符)。
批处理模式(脚本)- 您可以通过在扩展名为.pig 的单个文件中编写 Pig Latin 脚本来以批处理模式运行 Apache Pig 。
嵌入式模式(UDF) - Apache Pig 提供了在 Java 等编程语言中定义我们自己的函数(用户定义函数)的功能,并在我们的脚本中使用它们。
调用 Grunt Shell
您可以使用-x选项以所需模式(本地/MapReduce)调用 Grunt shell,如下所示。
本地模式 | MapReduce模式 |
---|---|
命令 - $ ./pig –x 本地 |
命令 - $ ./pig -x 映射缩减 |
输出- |
输出- |
这些命令中的任何一个都会为您提供 Grunt shell 提示符,如下所示。
grunt>
您可以使用“ctrl + d”退出 Grunt shell 。
调用Grunt shell后,您可以直接在其中输入Pig Latin语句来执行Pig脚本。
grunt> customers = LOAD 'customers.txt' USING PigStorage(',');
以批处理模式执行 Apache Pig
您可以在文件中编写整个 Pig Latin 脚本并使用–x 命令执行它。假设我们在名为Sample_script.pig 的文件中有一个 Pig 脚本,如下所示。
样本脚本.pig
student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',') as (id:int,name:chararray,city:chararray); Dump student;
现在,您可以执行上述文件中的脚本,如下所示。
本地模式 | MapReduce模式 |
---|---|
$ pig -x 本地Sample_script.pig | $ pig -x mapreduce Sample_script.pig |
注意- 我们将在后续章节中详细讨论如何在Bach 模式和嵌入模式下运行 Pig 脚本。
Apache Pig - Grunt Shell
调用 Grunt shell 后,您可以在 shell 中运行 Pig 脚本。除此之外,Grunt shell 还提供了某些有用的 shell 和实用程序命令。本章介绍 Grunt shell 提供的 shell 和实用程序命令。
注意- 在本章的某些部分中,使用了诸如“加载”和“存储”之类的命令。请参阅相应章节以获取有关它们的详细信息。
外壳命令
Apache Pig的Grunt shell主要用于编写Pig Latin脚本。在此之前,我们可以使用sh和fs调用任何 shell 命令。
sh 命令
使用sh命令,我们可以从 Grunt shell 调用任何 shell 命令。在 Grunt shell 中使用sh命令,我们无法执行 shell 环境中的命令 ( ex - cd )。
句法
下面给出sh命令的语法。
grunt> sh shell command parameters
例子
我们可以使用sh选项从 Grunt shell 调用 Linux shell 的ls命令,如下所示。在此示例中,它列出了/pig/bin/目录中的文件。
grunt> sh ls pig pig_1444799121955.log pig.cmd pig.py
fs 命令
使用fs命令,我们可以从 Grunt shell 调用任何 FsShell 命令。
句法
下面给出的是fs命令的语法。
grunt> sh File System command parameters
例子
我们可以使用 fs 命令从 Grunt shell 调用 HDFS 的 ls 命令。在以下示例中,它列出了 HDFS 根目录中的文件。
grunt> fs –ls Found 3 items drwxrwxrwx - Hadoop supergroup 0 2015-09-08 14:13 Hbase drwxr-xr-x - Hadoop supergroup 0 2015-09-09 14:52 seqgen_data drwxr-xr-x - Hadoop supergroup 0 2015-09-08 11:30 twitter_data
以同样的方式,我们可以使用fs命令从 Grunt shell 调用所有其他文件系统 shell 命令。
实用命令
Grunt shell 提供了一组实用命令。其中包括实用命令,例如clear、help、history、quit和set;以及从 Grunt shell 中控制 Pig 的exec、kill和run 等命令。下面给出了 Grunt shell 提供的实用命令的描述。
清除命令
clear命令用于清除Grunt shell的屏幕。
句法
您可以使用clear命令清除grunt shell的屏幕,如下所示。
grunt> clear
帮助命令
帮助命令为您提供 Pig 命令或 Pig 属性的列表。
用法
您可以使用帮助命令获取 Pig 命令列表,如下所示。
grunt> help Commands: <pig latin statement>; - See the PigLatin manual for details: http://hadoop.apache.org/pig File system commands:fs <fs arguments> - Equivalent to Hadoop dfs command: http://hadoop.apache.org/common/docs/current/hdfs_shell.html Diagnostic Commands:describe <alias>[::<alias] - Show the schema for the alias. Inner aliases can be described as A::B. explain [-script <pigscript>] [-out <path>] [-brief] [-dot|-xml] [-param <param_name>=<pCram_value>] [-param_file <file_name>] [<alias>] - Show the execution plan to compute the alias or for entire script. -script - Explain the entire script. -out - Store the output into directory rather than print to stdout. -brief - Don't expand nested plans (presenting a smaller graph for overview). -dot - Generate the output in .dot format. Default is text format. -xml - Generate the output in .xml format. Default is text format. -param <param_name - See parameter substitution for details. -param_file <file_name> - See parameter substitution for details. alias - Alias to explain. dump <alias> - Compute the alias and writes the results to stdout. Utility Commands: exec [-param <param_name>=param_value] [-param_file <file_name>] <script> - Execute the script with access to grunt environment including aliases. -param <param_name - See parameter substitution for details. -param_file <file_name> - See parameter substitution for details. script - Script to be executed. run [-param <param_name>=param_value] [-param_file <file_name>] <script> - Execute the script with access to grunt environment. -param <param_name - See parameter substitution for details. -param_file <file_name> - See parameter substitution for details. script - Script to be executed. sh <shell command> - Invoke a shell command. kill <job_id> - Kill the hadoop job specified by the hadoop job id. set <key> <value> - Provide execution parameters to Pig. Keys and values are case sensitive. The following keys are supported: default_parallel - Script-level reduce parallelism. Basic input size heuristics used by default. debug - Set debug on or off. Default is off. job.name - Single-quoted name for jobs. Default is PigLatin:<script name> job.priority - Priority for jobs. Values: very_low, low, normal, high, very_high. Default is normal stream.skippath - String that contains the path. This is used by streaming any hadoop property. help - Display this message. history [-n] - Display the list statements in cache. -n Hide line numbers. quit - Quit the grunt shell.
历史命令
此命令显示自调用 Grunt sell 以来迄今为止执行/使用的语句列表。
用法
假设自从打开 Grunt shell 以来我们已经执行了三个语句。
grunt> customers = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(','); grunt> orders = LOAD 'hdfs://localhost:9000/pig_data/orders.txt' USING PigStorage(','); grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',');
然后,使用历史命令将产生以下输出。
grunt> history customers = LOAD 'hdfs://localhost:9000/pig_data/customers.txt' USING PigStorage(','); orders = LOAD 'hdfs://localhost:9000/pig_data/orders.txt' USING PigStorage(','); student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',');
设置命令
set命令用于显示 Pig 中使用的键/为其分配值。
用法
使用此命令,您可以为以下键设置值。
钥匙 | 描述和值 |
---|---|
默认并行 | 您可以通过将任何整数作为值传递给此键来设置映射作业的减速器数量。 |
调试 | 您可以通过将 on/off 传递给此键来关闭或打开 Pig 中的调试功能。 |
职位名称 | 您可以通过向此键传递字符串值来将作业名称设置为所需的作业。 |
工作优先级 | 您可以通过将以下值之一传递给此键来设置作业的作业优先级 -
|
流.跳过路径 | 对于流式传输,您可以通过将所需路径以字符串形式传递给此键来设置不传输数据的路径。 |
退出命令
您可以使用此命令从 Grunt shell 退出。
用法
从 Grunt shell 退出,如下所示。
grunt> quit
现在让我们看一下可以从 Grunt shell 控制 Apache Pig 的命令。
执行命令
使用exec命令,我们可以从 Grunt shell 执行 Pig 脚本。
句法
下面给出了实用程序命令exec的语法。
grunt> exec [–param param_name = param_value] [–param_file file_name] [script]
例子
假设HDFS的/pig_data/目录下有一个名为student.txt的文件,其内容如下。
学生.txt
001,Rajiv,Hyderabad 002,siddarth,Kolkata 003,Rajesh,Delhi
并且,假设我们在HDFS的/pig_data/目录中有一个名为sample_script.pig的脚本文件,其内容如下。
样本脚本.pig
student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',') as (id:int,name:chararray,city:chararray); Dump student;
现在,让我们使用exec命令从 Grunt shell 执行上述脚本,如下所示。
grunt> exec /sample_script.pig
输出
exec命令执行sample_script.pig中的脚本。按照脚本中的指示,它将Student.txt文件加载到 Pig 中,并为您提供显示以下内容的 Dump 运算符的结果。
(1,Rajiv,Hyderabad) (2,siddarth,Kolkata) (3,Rajesh,Delhi)
杀命令
您可以使用此命令从 Grunt shell 终止作业。
句法
下面给出了kill命令的语法。
grunt> kill JobId
例子
假设有一个正在运行的 Pig 作业,其 ID 为Id_0055 ,您可以使用Kill命令从 Grunt shell 中终止它,如下所示。
grunt> kill Id_0055
运行命令
您可以使用run命令从 Grunt shell 运行 Pig 脚本
句法
下面给出了运行命令的语法。
grunt> run [–param param_name = param_value] [–param_file file_name] script
例子
假设HDFS的/pig_data/目录下有一个名为student.txt的文件,其内容如下。
学生.txt
001,Rajiv,Hyderabad 002,siddarth,Kolkata 003,Rajesh,Delhi
并且,假设我们在本地文件系统中有一个名为sample_script.pig的脚本文件,其中包含以下内容。
样本脚本.pig
student = LOAD 'hdfs://localhost:9000/pig_data/student.txt' USING PigStorage(',') as (id:int,name:chararray,city:chararray);
现在,让我们使用 run 命令从 Grunt shell 运行上述脚本,如下所示。
grunt> run /sample_script.pig
您可以使用Dump 运算符查看脚本的输出,如下所示。
grunt> Dump; (1,Rajiv,Hyderabad) (2,siddarth,Kolkata) (3,Rajesh,Delhi)
注意- exec和run命令之间的区别在于,如果我们使用run,则脚本中的语句在命令历史记录中可用。
猪拉丁语 – 基础知识
Pig Latin 是用于使用 Apache Pig 分析 Hadoop 中的数据的语言。在本章中,我们将讨论 Pig Latin 的基础知识,例如 Pig Latin 语句、数据类型、通用和关系运算符以及 Pig Latin UDF。
Pig Latin – 数据模型
正如前面章节所讨论的,Pig 的数据模型是完全嵌套的。关系是 Pig Latin 数据模型的最外层结构。这是一个袋子-
- 包是元组的集合。
- 元组是一组有序的字段。
- 字段是一段数据。
猪拉丁语 – Statemets
使用 Pig Latin 处理数据时,语句是基本结构。
这些陈述与关系有关。它们包括表达式和模式。
每个语句都以分号 (;) 结尾。
我们将通过语句使用 Pig Latin 提供的运算符来执行各种操作。
除了 LOAD 和 STORE 之外,在执行所有其他操作时,Pig Latin 语句将一个关系作为输入并生成另一个关系作为输出。
一旦您在 Grunt shell 中输入Load语句,就会执行其语义检查。要查看架构的内容,您需要使用Dump运算符。只有执行完dump操作后,才会执行将数据加载到文件系统的MapReduce作业。
例子
下面给出的是一个 Pig Latin 语句,它将数据加载到 Apache Pig。
grunt> Student_data = LOAD 'student_data.txt' USING PigStorage(',')as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
Pig Latin – 数据类型
下表描述了 Pig Latin 数据类型。
序列号 | 数据类型 | 描述和示例 |
---|---|---|
1 | 整数 | 表示有符号的 32 位整数。 示例:8 |
2 | 长的 | 表示有符号的 64 位整数。 示例:5L |
3 | 漂浮 | 表示有符号的 32 位浮点数。 示例:5.5F |
4 | 双倍的 | 表示 64 位浮点数。 示例:10.5 |
5 | 字符数组 | 表示 Unicode UTF-8 格式的字符数组(字符串)。 示例:“教程点” |
6 | 字节数组 | 表示字节数组 (blob)。 |
7 | 布尔值 | 代表一个布尔值。 示例:真/假。 |
8 | 约会时间 | 代表日期时间。 示例:1970-01-01T00:00:00.000+00:00 |
9 | 大整数 | 表示 Java BigInteger。 示例:60708090709 |
10 | 大十进制 | 表示 Java BigDecimal 示例:185.98376256272893883 |
复杂类型 | ||
11 | 元组 | 元组是一组有序的字段。 示例:(raja,30) |
12 | 包 | 包是元组的集合。 示例:{(raju,30),(Mohhammad,45)} |
13 | 地图 | Map 是一组键值对。 示例: [ '姓名'#'Raju', '年龄'#30] |
空值
上述所有数据类型的值都可以为 NULL。Apache Pig 处理空值的方式与 SQL 类似。
null 可以是未知值或不存在的值。它用作可选值的占位符。这些空值可以自然发生,也可以是操作的结果。
Pig Latin – 算术运算符
下表描述了 Pig Latin 的算术运算符。假设 a = 10 且 b = 20。
操作员 | 描述 | 例子 |
---|---|---|
+ | 加法- 添加运算符两侧的值 |
a + b 将得到 30 |
- | 减法- 从左手操作数中减去右手操作数 |
a − b 将给出 −10 |
* | 乘法- 将运算符两侧的值相乘 |
a * b 将给出 200 |
/ | 除法- 将左手操作数除以右手操作数 |
b / a 将给出 2 |
% | 模- 将左手操作数除以右手操作数并返回余数 |
b % a 将给出 0 |
?: | Bincond - 评估布尔运算符。它具有三个操作数,如下所示。 变量x = (表达式) ? 如果为 true ,则为 value1 :如果为 false ,则为value2。 |
b = (a == 1)? 20:30; 如果 a=1,则 b 的值为 20。 如果 a!=1,则 b 的值为 30。 |
案件 什么时候 然后 否则结束 |
Case - case 运算符相当于嵌套 bincond 运算符。 |
情况 f2 % 2 当 0 时则“偶数” 当 1 那么“奇数” 结尾 |
Pig Latin – 比较运算符
下表描述了 Pig Latin 的比较运算符。
操作员 | 描述 | 例子 |
---|---|---|
== | 等于- 检查两个操作数的值是否相等;如果是,则条件成立。 |
(a = b) 不正确 |
!= | 不等于- 检查两个操作数的值是否相等。如果值不相等,则条件成立。 |
(a != b) 为真。 |
> | 大于- 检查左操作数的值是否大于右操作数的值。如果是,则条件成立。 |
(a > b) 不正确。 |
< | 小于- 检查左操作数的值是否小于右操作数的值。如果是,则条件成立。 |
(a < b) 为真。 |
>= | 大于或等于- 检查左操作数的值是否大于或等于右操作数的值。如果是,则条件成立。 |
(a >= b) 不正确。 |
<= | 小于或等于- 检查左操作数的值是否小于或等于右操作数的值。如果是,则条件成立。 |
(a <= b) 为真。 |
火柴 | 模式匹配- 检查左侧的字符串是否与右侧的常量匹配。 |
f1 匹配 '.*tutorial.*' |
Pig Latin – 类型构造运算符
下表描述了 Pig Latin 的类型构造运算符。
操作员 | 描述 | 例子 |
---|---|---|
() | 元组构造函数运算符- 该运算符用于构造元组。 |
(拉朱,30 岁) |
{} | 包构造函数运算符- 该运算符用于构造一个包。 |
{(拉朱,30),(穆罕默德,45)} |
[] | 映射构造函数运算符- 该运算符用于构造元组。 |
[姓名#Raja,年龄#30] |
Pig Latin – 关系运算
下表描述了 Pig Latin 的关系运算符。
操作员 | 描述 |
---|---|
加载和存储 | |
加载 | 将文件系统(本地/HDFS)中的数据加载到关系中。 |
店铺 | 保存与文件系统(本地/HDFS)的关系。 |
过滤 | |
筛选 | 从关系中删除不需要的行。 |
清楚的 | 从关系中删除重复的行。 |
FOREACH,生成 | 基于数据列生成数据转换。 |
溪流 | 使用外部程序转换关系。 |
分组和加入 | |
加入 | 加入两个或多个关系。 |
集团 | 将数据分组为两个或多个关系。 |
团体 | 将数据分组到单个关系中。 |
叉 | 创建两个或多个关系的叉积。 |
排序 | |
命令 | 根据一个或多个字段(升序或降序)按排序顺序排列关系。 |
限制 | 从关系中获取有限数量的元组。 |
合并与拆分 | |
联盟 | 将两个或多个关系组合成一个关系。 |
分裂 | 将单个关系拆分为两个或多个关系。 |
诊断操作符 | |
倾倒 | 在控制台上打印关系的内容。 |
描述 | 描述关系的模式。 |
解释 | 查看计算关系的逻辑、物理或 MapReduce 执行计划。 |
阐明 | 查看一系列语句的逐步执行情况。 |
Apache Pig - 读取数据
一般来说,Apache Pig 运行在 Hadoop 之上。它是一种分析工具,可分析 Hadoop 文件系统中存在的大型数据集。要使用 Apache Pig 分析数据,我们必须首先将数据加载到 Apache Pig 中。本章介绍如何将数据从 HDFS 加载到 Apache Pig。
准备HDFS
在MapReduce模式下,Pig从HDFS读取(加载)数据并将结果存储回HDFS。因此,让我们启动 HDFS 并在 HDFS 中创建以下示例数据。
学生卡 | 名 | 姓 | 电话 | 城市 |
---|---|---|---|---|
001 | 拉吉夫 | 雷迪 | 9848022337 | 海得拉巴 |
002 | 悉达斯 | 巴塔查亚 | 9848022338 | 加尔各答 |
003 | 拉杰什 | 卡纳 | 9848022339 | 德里 |
004 | 普雷蒂 | 阿加瓦尔 | 9848022330 | 浦那 |
005 | 特鲁普蒂 | 莫汉蒂 | 9848022336 | 布瓦内什瓦尔 |
006 | 阿卡纳 | 米斯拉 | 9848022335 | 钦奈 |
上面的数据集包含六名学生的个人详细信息,例如 ID、名字、姓氏、电话号码和城市。
第 1 步:验证 Hadoop
首先,使用Hadoop版本命令验证安装,如下所示。
$ hadoop version
如果您的系统包含 Hadoop,并且设置了 PATH 变量,那么您将得到以下输出 -
Hadoop 2.6.0 Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r e3496499ecb8d220fba99dc5ed4c99c8f9e33bb1 Compiled by jenkins on 2014-11-13T21:10Z Compiled with protoc 2.5.0 From source with checksum 18e43357c8f927c0695f1e9522859d6a This command was run using /home/Hadoop/hadoop/share/hadoop/common/hadoop common-2.6.0.jar
第2步:启动HDFS
浏览Hadoop的sbin目录,启动yarn和Hadoop dfs(分布式文件系统),如下图。
cd /$Hadoop_Home/sbin/ $ start-dfs.sh localhost: starting namenode, logging to /home/Hadoop/hadoop/logs/hadoopHadoop-namenode-localhost.localdomain.out localhost: starting datanode, logging to /home/Hadoop/hadoop/logs/hadoopHadoop-datanode-localhost.localdomain.out Starting secondary namenodes [0.0.0.0] starting secondarynamenode, logging to /home/Hadoop/hadoop/logs/hadoop-Hadoopsecondarynamenode-localhost.localdomain.out $ start-yarn.sh starting yarn daemons starting resourcemanager, logging to /home/Hadoop/hadoop/logs/yarn-Hadoopresourcemanager-localhost.localdomain.out localhost: starting nodemanager, logging to /home/Hadoop/hadoop/logs/yarnHadoop-nodemanager-localhost.localdomain.out
步骤3:在HDFS中创建目录
在 Hadoop DFS 中,您可以使用命令mkdir创建目录。在HDFS 中的所需路径中创建一个名为Pig_Data的新目录,如下所示。
$cd /$Hadoop_Home/bin/ $ hdfs dfs -mkdir hdfs://localhost:9000/Pig_Data
第四步:将数据放入HDFS
Pig 的输入文件在单独的行中包含每个元组/记录。记录的实体由分隔符分隔(在我们的示例中我们使用“,”)。
在本地文件系统中,创建一个包含数据的输入文件student_data.txt,如下所示。
001,Rajiv,Reddy,9848022337,Hyderabad 002,siddarth,Battacharya,9848022338,Kolkata 003,Rajesh,Khanna,9848022339,Delhi 004,Preethi,Agarwal,9848022330,Pune 005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar 006,Archana,Mishra,9848022335,Chennai.
现在,使用put命令将文件从本地文件系统移动到 HDFS,如下所示。(您也可以使用copyFromLocal命令。)
$ cd $HADOOP_HOME/bin $ hdfs dfs -put /home/Hadoop/Pig/Pig_Data/student_data.txt dfs://localhost:9000/pig_data/
验证文件
可以使用cat命令验证文件是否已经移入HDFS,如下所示。
$ cd $HADOOP_HOME/bin $ hdfs dfs -cat hdfs://localhost:9000/pig_data/student_data.txt
输出
您可以看到该文件的内容,如下所示。
15/10/01 12:16:55 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 001,Rajiv,Reddy,9848022337,Hyderabad 002,siddarth,Battacharya,9848022338,Kolkata 003,Rajesh,Khanna,9848022339,Delhi 004,Preethi,Agarwal,9848022330,Pune 005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar 006,Archana,Mishra,9848022335,Chennai
负载操作符
您可以使用Pig Latin的LOAD运算符将数据从文件系统(HDFS/本地)加载到 Apache Pig 中。
句法
load 语句由两部分组成,由“=”运算符分隔。在左侧,我们需要提及要存储数据的关系的名称,在右侧,我们必须定义如何存储数据。下面给出了Load运算符的语法。
Relation_name = LOAD 'Input file path' USING function as schema;
在哪里,
relation_name - 我们必须提及我们想要存储数据的关系。
输入文件路径- 我们必须提及存储文件的 HDFS 目录。(在MapReduce模式下)
function - 我们必须从 Apache Pig 提供的加载函数集中选择一个函数(BinStorage、JsonLoader、PigStorage、TextLoader)。
架构- 我们必须定义数据的架构。我们可以定义所需的模式如下 -
(column1 : data type, column2 : data type, column3 : data type);
注意- 我们加载数据而不指定模式。在这种情况下,这些列将被寻址为 $01、$02 等......(检查)。
例子
作为示例,让我们使用LOAD命令在名为Student的模式下加载 Pig 中的Student_data.txt中的数据。
启动 Pig Grunt shell
首先,打开Linux终端。在 MapReduce 模式下启动 Pig Grunt shell,如下所示。
$ Pig –x mapreduce
它将启动 Pig Grunt shell,如下所示。
15/10/01 12:33:37 INFO pig.ExecTypeProvider: Trying ExecType : LOCAL 15/10/01 12:33:37 INFO pig.ExecTypeProvider: Trying ExecType : MAPREDUCE 15/10/01 12:33:37 INFO pig.ExecTypeProvider: Picked MAPREDUCE as the ExecType 2015-10-01 12:33:38,080 [main] INFO org.apache.pig.Main - Apache Pig version 0.15.0 (r1682971) compiled Jun 01 2015, 11:44:35 2015-10-01 12:33:38,080 [main] INFO org.apache.pig.Main - Logging error messages to: /home/Hadoop/pig_1443683018078.log 2015-10-01 12:33:38,242 [main] INFO org.apache.pig.impl.util.Utils - Default bootup file /home/Hadoop/.pigbootup not found 2015-10-01 12:33:39,630 [main] INFO org.apache.pig.backend.hadoop.executionengine.HExecutionEngine - Connecting to hadoop file system at: hdfs://localhost:9000 grunt>
执行加载语句
现在,通过在 Grunt shell 中执行以下 Pig Latin 语句,将文件Student_data.txt中的数据加载到 Pig 中。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt' USING PigStorage(',') as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
以下是对上述语句的描述。
关系名称 | 我们已将数据存储在 schema Student中。 | ||||||||||||
输入文件路径 | 我们正在从文件student_data.txt中读取数据,该文件位于HDFS的/pig_data/目录中。 | ||||||||||||
存储功能 | 我们使用了PigStorage()函数。它将数据加载和存储为结构化文本文件。它采用分隔符作为参数,使用该分隔符分隔元组的每个实体。默认情况下,它采用“\t”作为参数。 | ||||||||||||
图式 | 我们使用以下模式存储数据。
|
注意- load语句将简单地将数据加载到 Pig 中的指定关系中。要验证Load语句的执行,您必须使用后续章节中讨论的诊断运算符。
Apache Pig - 存储数据
在上一章中,我们学习了如何将数据加载到 Apache Pig 中。您可以使用存储运算符将加载的数据存储在文件系统中。本章介绍如何使用Store运算符在 Apache Pig 中存储数据。
句法
下面给出了 Store 语句的语法。
STORE Relation_name INTO ' required_directory_path ' [USING function];
例子
假设我们在HDFS中有一个文件student_data.txt,其内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad 002,siddarth,Battacharya,9848022338,Kolkata 003,Rajesh,Khanna,9848022339,Delhi 004,Preethi,Agarwal,9848022330,Pune 005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar 006,Archana,Mishra,9848022335,Chennai.
我们已经使用 LOAD 运算符将其读入关系学生中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt' USING PigStorage(',') as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
现在,让我们将关系存储在 HDFS 目录“/pig_Output/”中,如下所示。
grunt> STORE student INTO ' hdfs://localhost:9000/pig_Output/ ' USING PigStorage (',');
输出
执行store语句后,您将得到以下输出。将创建一个具有指定名称的目录,数据将存储在其中。
2015-10-05 13:05:05,429 [main] INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer. MapReduceLau ncher - 100% complete 2015-10-05 13:05:05,429 [main] INFO org.apache.pig.tools.pigstats.mapreduce.SimplePigStats - Script Statistics: HadoopVersion PigVersion UserId StartedAt FinishedAt Features 2.6.0 0.15.0 Hadoop 2015-10-0 13:03:03 2015-10-05 13:05:05 UNKNOWN Success! Job Stats (time in seconds): JobId Maps Reduces MaxMapTime MinMapTime AvgMapTime MedianMapTime job_14459_06 1 0 n/a n/a n/a n/a MaxReduceTime MinReduceTime AvgReduceTime MedianReducetime Alias Feature 0 0 0 0 student MAP_ONLY OutPut folder hdfs://localhost:9000/pig_Output/ Input(s): Successfully read 0 records from: "hdfs://localhost:9000/pig_data/student_data.txt" Output(s): Successfully stored 0 records in: "hdfs://localhost:9000/pig_Output" Counters: Total records written : 0 Total bytes written : 0 Spillable Memory Manager spill count : 0 Total bags proactively spilled: 0 Total records proactively spilled: 0 Job DAG: job_1443519499159_0006 2015-10-05 13:06:06,192 [main] INFO org.apache.pig.backend.hadoop.executionengine .mapReduceLayer.MapReduceLau ncher - Success!
确认
您可以验证存储的数据,如下所示。
步骤1
首先,使用ls命令列出名为pig_output的目录中的文件,如下所示。
hdfs dfs -ls 'hdfs://localhost:9000/pig_Output/' Found 2 items rw-r--r- 1 Hadoop supergroup 0 2015-10-05 13:03 hdfs://localhost:9000/pig_Output/_SUCCESS rw-r--r- 1 Hadoop supergroup 224 2015-10-05 13:03 hdfs://localhost:9000/pig_Output/part-m-00000
您可以观察到执行store语句后创建了两个文件。
第2步
使用cat命令,列出名为part-m-00000的文件的内容,如下所示。
$ hdfs dfs -cat 'hdfs://localhost:9000/pig_Output/part-m-00000' 1,Rajiv,Reddy,9848022337,Hyderabad 2,siddarth,Battacharya,9848022338,Kolkata 3,Rajesh,Khanna,9848022339,Delhi 4,Preethi,Agarwal,9848022330,Pune 5,Trupthi,Mohanthy,9848022336,Bhuwaneshwar 6,Archana,Mishra,9848022335,Chennai
Apache Pig - 诊断运算符
load语句将简单地将数据加载到 Apache Pig 中的指定关系中。要验证Load语句的执行,您必须使用诊断运算符。Pig Latin 提供四种不同类型的诊断运算符 -
- 转储操作符
- 描述运算符
- 解释运算符
- 插图操作员
在本章中,我们将讨论 Pig Latin 的 Dump 运算符。
转储操作员
Dump运算符用于运行 Pig Latin 语句并将结果显示在屏幕上。一般用于调试目的。
句法
下面给出的是Dump运算符的语法。
grunt> Dump Relation_Name
例子
假设我们在HDFS中有一个文件student_data.txt,其内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad 002,siddarth,Battacharya,9848022338,Kolkata 003,Rajesh,Khanna,9848022339,Delhi 004,Preethi,Agarwal,9848022330,Pune 005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar 006,Archana,Mishra,9848022335,Chennai.
我们已经使用 LOAD 运算符将其读入关系学生中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt' USING PigStorage(',') as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
现在,让我们使用Dump 运算符打印关系的内容,如下所示。
grunt> Dump student
一旦执行上述Pig Latin语句,它将启动一个 MapReduce 作业从 HDFS 读取数据。它将产生以下输出。
2015-10-01 15:05:27,642 [main] INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MapReduceLauncher - 100% complete 2015-10-01 15:05:27,652 [main] INFO org.apache.pig.tools.pigstats.mapreduce.SimplePigStats - Script Statistics: HadoopVersion PigVersion UserId StartedAt FinishedAt Features 2.6.0 0.15.0 Hadoop 2015-10-01 15:03:11 2015-10-01 05:27 UNKNOWN Success! Job Stats (time in seconds): JobId job_14459_0004 Maps 1 Reduces 0 MaxMapTime n/a MinMapTime n/a AvgMapTime n/a MedianMapTime n/a MaxReduceTime 0 MinReduceTime 0 AvgReduceTime 0 MedianReducetime 0 Alias student Feature MAP_ONLY Outputs hdfs://localhost:9000/tmp/temp580182027/tmp757878456, Input(s): Successfully read 0 records from: "hdfs://localhost:9000/pig_data/ student_data.txt" Output(s): Successfully stored 0 records in: "hdfs://localhost:9000/tmp/temp580182027/ tmp757878456" Counters: Total records written : 0 Total bytes written : 0 Spillable Memory Manager spill count : 0Total bags proactively spilled: 0 Total records proactively spilled: 0 Job DAG: job_1443519499159_0004 2015-10-01 15:06:28,403 [main] INFO org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.MapReduceLau ncher - Success! 2015-10-01 15:06:28,441 [main] INFO org.apache.pig.data.SchemaTupleBackend - Key [pig.schematuple] was not set... will not generate code. 2015-10-01 15:06:28,485 [main] INFO org.apache.hadoop.mapreduce.lib.input.FileInputFormat - Total input paths to process : 1 2015-10-01 15:06:28,485 [main] INFO org.apache.pig.backend.hadoop.executionengine.util.MapRedUtil - Total input paths to process : 1 (1,Rajiv,Reddy,9848022337,Hyderabad) (2,siddarth,Battacharya,9848022338,Kolkata) (3,Rajesh,Khanna,9848022339,Delhi) (4,Preethi,Agarwal,9848022330,Pune) (5,Trupthi,Mohanthy,9848022336,Bhuwaneshwar) (6,Archana,Mishra,9848022335,Chennai)
Apache Pig - 描述运算符
描述运算符用于查看关系的模式。
句法
描述运算符的语法如下 -
grunt> Describe Relation_name
例子
假设我们在HDFS中有一个文件student_data.txt,其内容如下。
001,Rajiv,Reddy,9848022337,Hyderabad 002,siddarth,Battacharya,9848022338,Kolkata 003,Rajesh,Khanna,9848022339,Delhi 004,Preethi,Agarwal,9848022330,Pune 005,Trupthi,Mohanthy,9848022336,Bhuwaneshwar 006,Archana,Mishra,9848022335,Chennai.
我们已经使用 LOAD 运算符将其读入关系学生中,如下所示。
grunt> student = LOAD 'hdfs://localhost:9000/pig_data/student_data.txt' USING PigStorage(',') as ( id:int, firstname:chararray, lastname:chararray, phone:chararray, city:chararray );
现在,让我们描述名为Student的关系并验证模式是否为 sho