Teradata 简明教程

Teradata - Quick Guide

Teradata - Introduction

What is Teradata?

Teradata 是流行的关系数据库管理系统之一。它主要适用于构建大型数据仓库应用程序。Teradata 通过并行性的概念实现了这一点。它是由 Teradata 公司开发的。

History of Teradata

以下是 Teradata 历史的快速摘要,列出了主要里程碑。

  1. 1979 - Teradata 成立。

  2. 1984 - 发布第一台数据库计算机 DBC/1012。

  3. 1986 - 《财富》杂志将 Teradata 评为“年度产品”。

  4. 1999 - 使用 Teradata 的世界上最大的数据库,容量为 130 TB。

  5. 2002 - 发布带有分区主索引和压缩功能的 Teradata V2R5。

  6. 2006 - 推出 Teradata 主数据管理解决方案。

  7. 2008 - 发布了带有主动数据仓库的 Teradata 13.0。

  8. 2011 - 收购 Teradata Aster,并进入高级分析领域。

  9. 2012 - 引入了 Teradata 14.0。

  10. 2014 - 引入了 Teradata 15.0。

Features of Teradata

以下是 Teradata 的一些功能 -

  1. Unlimited Parallelism - Teradata 数据库系统基于大规模并行处理 (MPP) 架构。MPP 架构均匀地将工作负载划分为整个系统。Teradata 系统在其流程之间拆分任务,并并行运行这些流程以确保快速完成任务。

  2. Shared Nothing Architecture - Teradata 架构称为无共享架构。Teradata 节点、其访问模块处理器 (AMP) 和与 AMP 关联的磁盘独立运行。它们与他人不共享。

  3. Linear Scalability - Teradata 系统具有很高的可扩展性。它们可以扩展到 2048 个节点。例如,可以通过将 AMP 的数量加倍来将系统容量加倍。

  4. Connectivity - Teradata 可以连接到信道连接系统,例如大型机或网络连接系统。

  5. Mature Optimizer - Teradata 优化器是市场上成熟的优化器之一。它从一开始就被设计为并行的。它针对每个版本进行了优化。

  6. SQL - Teradata 支持工业标准 SQL 来与存储在表中的数据进行交互。除此之外,它还提供了自己的扩展。

  7. Robust Utilities - Teradata 提供了强大的实用工具来从 Teradata 系统导入/导出数据,例如 FastLoad、MultiLoad、FastExport 和 TPT。

  8. Automatic Distribution - Teradata 会自动将数据均匀分布到各个磁盘,而无需任何人工干预。

Teradata - Installation

Teradata 提供了适用于 VMWARE 的 Teradata Express,这是一个全面运行的 Teradata 虚拟机。它提供了高达 1 TB 的存储空间。Teradata 同时提供了 40 GB 和 1 TB 版本的 VMware。

Prerequisites

由于 VM 是 64 位,因此你的 CPU 必须支持 64 位。

Installation Steps for Windows

Step 2 − 提取文件并指定目标文件夹。

Step 3 − 从以下链接下载 VMWare Workstation 播放器, https://my.vmware.com/web/vmware/downloads 。它适用于 Windows 和 Linux。下载适用于 Windows 的 VMWARE Workstation 播放器。

vmware workstation player

Step 4 − 下载完成后,安装软件。

Step 5 − 安装完成后,运行 VMWARE 客户端。

Step 6 − 选择“打开虚拟机”。浏览解压的 Teradata VMWare 文件夹并选择扩展名为 .vmdk 的文件。

open virtual machine

Step 7 − Teradata VMWare 已添加到 VMWare 客户端。选择添加的 Teradata VMware 然后单击“播放虚拟机”。

play virtual machine

Step 8 − 如果软件更新中弹出窗口,您可以选择“稍后提醒我”。

Step 9 − 输入用户名 root,按 tab 并输入密码 root,再次按 Enter。

welcome tdexpress

Step 10 − 桌面出现以下屏幕后,双击“root 的主页”。然后双击“Genome 终端”。这将打开 Shell。

open shell

Step 11 − 在以下 shell 中,输入命令 /etc/init.d/tpa start。这将启动 Teradata 服务器。

start teradata server

Starting BTEQ

BTEQ 实用程序用于交互方式提交 SQL 查询。以下是启动 BTEQ 实用程序的步骤。

Step 1 − 输入命令 /sbin/ifconfig 并记下 VMWare 的 IP 地址。

Step 2 − 运行命令 bteq。在登录提示符下,输入命令。

Logon <ipaddress>/dbc,dbc; 并在密码提示符下,输入密码 dbc;

start bteq

您可以使用 BTEQ 登录到 Teradata 系统并运行任何 SQL 查询。

Teradata - Architecture

Teradata 架构基于大规模并行处理 (MPP) 架构。Teradata 的主要组件有解析引擎、BYNET 和访问模块处理器 (AMP)。下图显示了 Teradata 节点的高层次架构。

teradata node architecture

Components of Teradata

Teradata 的关键组件如下所示 −

  1. Node − 它是 Teradata 系统中的基本单元。Teradata 系统中的每个单独服务器称为一个节点。一个节点包含其自己的操作系统、CPU、内存、Teradata RDBMS 软件的副本和磁盘空间。一个机柜由一个或多个节点组成。

  2. Parsing Engine − 解析引擎负责接收来自客户端的查询并准备一个高效的执行计划。解析引擎的职责有 −接收来自客户端的 SQL 查询解析 SQL 查询并检查语法错误检查用户是否对 SQL 查询中使用的对象拥有所需权限检查 SQL 中使用的对象是否实际存在准备执行计划以执行 SQL 查询并将其传递给 BYNET接收来自 AMP 的结果并发送给客户端

  3. Message Passing Layer − 消息传递层称为 BYNET,它是 Teradata 系统中的网络层。它允许在 PE 和 AMP 之间以及在节点之间进行通信。它接收来自解析引擎的执行计划并发送给 AMP。同样,它接收来自 AMP 的结果并发送给解析引擎。

  4. Access Module Processor (AMP) − AMP(称为虚拟处理器 (vprocs))实际上负责存储和检索数据。AMP 从解析引擎接收数据和执行计划,执行任何数据类型转换、聚合、筛选、排序并将数据存储在与它们关联的磁盘中。来自表的记录在系统中的 AMP 之间均匀分布。每个 AMP 都与存储数据的磁盘集相关联。只有该 AMP 可以读写磁盘中的数据。

Storage Architecture

当客户端运行查询以插入记录时,解析引擎会将这些记录发送给 BYNET。BYNET 检索记录并将行发送给目标 AMP。AMP 将这些记录存储在其磁盘上。下图显示了 Teradata 的存储架构。

storage architecture

Retrieval Architecture

当客户端运行查询以检索记录时,解析引擎会向 BYNET 发送一个请求。BYNET 将检索请求发送给适当的 AMP。然后,AMP 会并行搜索其磁盘并识别所需记录,然后发送给 BYNET。然后 BYNET 会将记录发送给解析引擎,解析引擎会将其发送给客户端。以下是 Teradata 的检索架构。

retrieval architecture

Teradata - Relational Concepts

关系数据库管理系统 (RDBMS) 是一种 DBMS 软件,有助于与数据库交互。它们使用结构化查询语言 (SQL) 与存储在表中的数据交互。

Database

数据库是逻辑相关数据的集合。许多用户出于不同的目的对其进行访问。例如,销售数据库包含存储在许多表中的整个销售信息。

Tables

表是 RDBMS 中存储数据的基本单位。表是行和列的集合。以下是 employee 表的示例。

EmployeeNo

FirstName

LastName

BirthDate

101

Mike

James

1/5/1980

104

Alex

Stuart

11/6/1984

102

Robert

Williams

3/5/1983

105

Robert

James

12/1/1984

103

Peter

Paul

4/1/1983

Columns

一列中包含类似的数据。例如,Employee 表中的列 BirthDate 包含所有员工的 birth_date 信息。

BirthDate

1/5/1980

11/6/1984

3/5/1983

12/1/1984

4/1/1983

Row

行是所有列的一个实例。例如,在 employee 表中,一行包含关于单个员工的信息。

EmployeeNo

FirstName

LastName

BirthDate

101

Mike

James

1/5/1980

Primary Key

主键用于唯一标识表中的行。主键列中不允许重复的值,并且它们不能接受 NULL 值。它是表中的一个必填字段。

Foreign Key

外键用于建立表之间的关系。子表中的外键被定义为主表中的主键。一个表可以有多个外键。它可以接受重复值和空值。外键在表中是可选的。

Teradata - Data Types

表中的每一行都与数据类型相关联。数据类型指定将存储在该列中的值类型。Teradata 支持多种数据类型。以下是一些常用的数据类型。

Data Types

Length (Bytes)

Range of values

BYTEINT

1

-128 to +127

SMALLINT

2

-32768 to +32767

INTEGER

4

-2,147,483,648 to +2147,483,647

BIGINT

8

-9,233,372,036,854,775,80 8 到 +9,233,372,036,854,775,8 07

DECIMAL

1-16

NUMERIC

1-16

FLOAT

8

IEEE format

CHAR

Fixed Format

1-64,000

VARCHAR

Variable

1-64,000

DATE

4

YYYYYMMDD

TIME

6 or 8

HHMMSS.nnnnnn or HHMMSS.nnnnnn+HHMM

TIMESTAMP

10 or 12

YYMMDDHHMMSS.nnnnnn or YYMMDDHHMMSS.nnnnnn +HHMM

Teradata - Tables

关系模型中的表定义为数据的集合。它们表示为行和列。

Table Types

类型 Teradata 支持不同类型的表。

  1. Permanent Table − 这是默认表,它包含用户插入的数据,并永久存储数据。

  2. Volatile Table − 仅在用户会话期间保留插入易失表的数据。该表和数据在会话结束时被删除。这些表主要用于在数据转换期间保存中间数据。

  3. Global Temporary Table − 全局临时表是持续的,但该表中的数据在用户会话结束时被删除。

  4. Derived Table − 派生数据表拥有查询中的中间结果。这些表存在于用来创建、使用和删除它们的查询中。

Set Versus Multiset

Teradata 根据重复记录的处理方式将表分类为 SET 或 MULTISET 表。定义为 SET 表的表不存储重复记录,而 MULTISET 表则可以存储重复记录。

Sr.No

Table Commands & Description

1

Create Table Teradata 中使用 CREATE TABLE 命令来创建表。

2

Alter Table Teradata 中使用 ALTER TABLE 命令在现有表中添加或删除列。

3

Drop Table Teradata 中使用 DROP TABLE 命令来删除表。

Teradata - Data Manipulation

本章介绍用于处理存储在 Teradata 表中的数据的 SQL 命令。

Insert Records

INSERT INTO 语句用于向表中插入记录。

Syntax

以下是 INSERT INTO 的通用语法。

INSERT INTO <tablename>
(column1, column2, column3,…)
VALUES
(value1, value2, value3 …);

Example

以下示例向 employee 表中插入记录。

INSERT INTO Employee (
   EmployeeNo,
   FirstName,
   LastName,
   BirthDate,
   JoinedDate,
   DepartmentNo
)
VALUES (
   101,
   'Mike',
   'James',
   '1980-01-05',
   '2005-03-27',
   01
);

插入上述查询后,可以使用 SELECT 语句从表中查看记录。

EmployeeNo

FirstName

LastName

JoinedDate

DepartmentNo

BirthDate

101

Mike

James

3/27/2005

1

1/5/1980

Insert from Another Table

INSERT SELECT 语句用于从另一个表中插入记录。

Syntax

以下是 INSERT INTO 的通用语法。

INSERT INTO <tablename>
(column1, column2, column3,…)
SELECT
column1, column2, column3…
FROM
<source table>;

Example

以下示例向 employee 表中插入记录。在运行以下插入查询之前,创建一个名为 Employee_Bkup 的表,其列定义与 employee 表相同。

INSERT INTO Employee_Bkup (
   EmployeeNo,
   FirstName,
   LastName,
   BirthDate,
   JoinedDate,
   DepartmentNo
)
SELECT
   EmployeeNo,
   FirstName,
   LastName,
   BirthDate,
   JoinedDate,
   DepartmentNo
FROM
   Employee;

执行上述查询时,将把 employee 表中的所有记录插入到 employee_bkup 表中。

Rules

  1. VALUES 列表中指定列数应与 INSERT INTO 子句中指定的列匹配。

  2. 值对于 NOT NULL 列是必需的。

  3. 如果没有指定任何值,则会为可接受空值字段插入 NULL。

  4. VALUES 子句中指定的列的数据类型应与 INSERT 子句中列的数据类型兼容。

Update Records

UPDATE 语句用于更新表中的记录。

Syntax

以下是 UPDATE 的通用语法。

UPDATE <tablename>
SET <columnnamme> = <new value>
[WHERE condition];

Example

下面的示例将雇员 101 的员工部门更新为 03。

UPDATE Employee
SET DepartmentNo = 03
WHERE EmployeeNo = 101;

在下面的输出中,您可以看到雇员编号为 101 的部门编号从 1 更新为 3。

SELECT Employeeno, DepartmentNo FROM Employee;
*** Query completed. One row found. 2 columns returned.
*** Total elapsed time was 1 second.
EmployeeNo    DepartmentNo
-----------  -------------
   101             3

Rules

  1. 您可以更新表的一个或多个值。

  2. 如果未指定 WHERE 条件,则会影响表的所有行。

  3. 您可以使用其他表中的值更新表。

Delete Records

DELETE FROM 语句用于更新表中的记录。

Syntax

以下是 DELETE FROM 的一般语法。

DELETE FROM  <tablename>
[WHERE condition];

Example

下面的示例从表 employee 中删除雇员 101。

DELETE FROM Employee
WHERE EmployeeNo = 101;

在下面的输出中,您可以看到雇员 101 已从表中删除。

SELECT EmployeeNo FROM Employee;
*** Query completed. No rows found.
*** Total elapsed time was 1 second.

Rules

  1. 您可以更新表的一个或多个记录。

  2. 如果未指定 WHERE 条件,则会删除表的所有行。

  3. 您可以使用其他表中的值更新表。

Teradata - SELECT Statement

SELECT 语句用于从表中检索记录。

Syntax

以下是 SELECT 语句的基本语法。

SELECT
column 1, column 2, .....
FROM
tablename;

Example

考虑以下员工表。

EmployeeNo

FirstName

LastName

JoinedDate

DepartmentNo

BirthDate

101

Mike

James

3/27/2005

1

1/5/1980

102

Robert

Williams

4/25/2007

2

3/5/1983

103

Peter

Paul

3/21/2007

2

4/1/1983

104

Alex

Stuart

2/1/2008

2

11/6/1984

105

Robert

James

1/4/2008

3

12/1/1984

下面是 SELECT 语句的一个示例。

SELECT EmployeeNo,FirstName,LastName
FROM Employee;

执行此查询时,它会从 employee 表中提取 EmployeeNo、FirstName 和 LastName 列。

 EmployeeNo            FirstName                       LastName
-----------  ------------------------------  ---------------------------
   101                   Mike                            James
   104                   Alex                            Stuart
   102                   Robert                          Williams
   105                   Robert                          James
   103                   Peter                           Paul

如果您想提取表中的所有列,您可以使用以下命令,而不必列出所有列。

SELECT * FROM Employee;

上述查询将从 employee 表中提取所有记录。

WHERE Clause

WHERE 子句用于过滤 SELECT 语句返回的记录。一个条件与 WHERE 子句相关联。只有满足 WHERE 子句中条件的记录才会被返回。

Syntax

下面是带 WHERE 子句的 SELECT 语句的语法。

SELECT * FROM tablename
WHERE[condition];

Example

以下查询提取 EmployeeNo 为 101 的记录。

SELECT * FROM Employee
WHERE EmployeeNo = 101;

执行此查询时,它返回以下记录。

 EmployeeNo          FirstName                      LastName
----------- ------------------------------ -----------------------------
   101                 Mike                           James

ORDER BY

执行 SELECT 语句时,返回的行没有任何特定顺序。ORDER BY 子句用于以升序/降序在任何列上排列记录。

Syntax

以下是带 ORDER BY 子句的 SELECT 语句的语法。

SELECT * FROM tablename
ORDER BY column 1, column 2..;

Example

以下查询从 employee 表中提取记录,并按 FirstName 对结果进行排序。

SELECT * FROM Employee
ORDER BY FirstName;

执行以上查询后,将产生以下输出。

 EmployeeNo         FirstName                      LastName
----------- ------------------------------ -----------------------------
    104               Alex                           Stuart
    101               Mike                           James
    103               Peter                          Paul
    102               Robert                         Williams
    105               Robert                         James

GROUP BY

GROUP BY 子句与 SELECT 语句配合使用,并将类似的记录整理到组中。

Syntax

以下是带有 GROUP BY 子句的 SELECT 语句的语法。

SELECT column 1, column2 …. FROM tablename
GROUP BY column 1, column 2..;

Example

以下示例按 DepartmentNo 列对记录进行分组,并识别每个部门的总数。

SELECT DepartmentNo,Count(*) FROM
Employee
GROUP BY DepartmentNo;

执行以上查询后,将产生以下输出。

 DepartmentNo    Count(*)
------------  -----------
     3             1
     1             1
     2             3

Teradata - Logical and Conditional Operators

Teradata 支持以下逻辑和条件运算符。这些运算符用于执行比较并组合多个条件。

Syntax

Meaning

>

Greater than

<

Less than

>=

大于或等于

小于或等于

=

Equal to

BETWEEN

If values within range

IN

If values in <expression>

NOT IN

如果值不在 <expression> 中

IS NULL

If value is NULL

IS NOT NULL

如果值不为 NULL

AND

组合多个条件。仅当所有条件都满足时才评估为真

OR

组合多个条件。仅当任一条件满足时才评估为真。

NOT

颠倒条件的含义

BETWEEN

BETWEEN 命令用于检查某个值是否在一个值范围内。

Example

考虑以下员工表。

EmployeeNo

FirstName

LastName

JoinedDate

DepartmentNo

BirthDate

101

Mike

James

3/27/2005

1

1/5/1980

102

Robert

Williams

4/25/2007

2

3/5/1983

103

Peter

Paul

3/21/2007

2

4/1/1983

104

Alex

Stuart

2/1/2008

2

11/6/1984

105

Robert

James

1/4/2008

3

12/1/1984

以下示例获取雇员编号在 101、102 和 103 之间的记录。

SELECT EmployeeNo, FirstName FROM
Employee
WHERE EmployeeNo BETWEEN 101 AND 103;

在执行上述查询时,它返回雇员编号在 101 和 103 之间的雇员记录。

*** Query completed. 3 rows found. 2 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo            FirstName
-----------  ------------------------------
   101                   Mike
   102                   Robert
   103                   Peter

IN

IN 命令用于针对给定的值列表检查值。

Example

以下示例获取雇员编号为 101、102 和 103 的记录。

SELECT EmployeeNo, FirstName FROM
Employee
WHERE EmployeeNo in (101,102,103);

上述查询返回以下记录。

*** Query completed. 3 rows found. 2 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo            FirstName
-----------  ------------------------------
   101                   Mike
   102                   Robert
   103                   Peter

NOT IN

NOT IN 命令颠倒了 IN 命令的结果。它获取与给定列表不匹配的值的记录。

Example

以下示例提取了不在 101、102 和 103 中的员工编号记录。

SELECT * FROM
Employee
WHERE EmployeeNo not in (101,102,103);

上述查询返回以下记录。

*** Query completed. 2 rows found. 6 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo          FirstName                      LastName
----------- ------------------------------ -----------------------------
    104                Alex                          Stuart
    105                Robert                        James

Teradata - SET Operators

集合运算符结合了来自多个 SELECT 语句的结果。这可能看起来类似于联接,但联接合并了来自多个表的列,而集合运算符合并了来自多行中的行。

Rules

  1. 每个 SELECT 语句的列数应相同。

  2. 每个 SELECT 中的数据类型必须兼容。

  3. ORDER BY 应仅包含在最终的 SELECT 语句中。

UNION

UNION 语句用于结合来自多个 SELECT 语句的结果。它忽略了重复项。

Syntax

以下是 UNION 语句的基本语法。

SELECT col1, col2, col3…
FROM
<table 1>
[WHERE condition]
UNION

SELECT col1, col2, col3…
FROM
<table 2>
[WHERE condition];

Example

考虑以下员工表和薪资表。

EmployeeNo

FirstName

LastName

JoinedDate

DepartmentNo

BirthDate

101

Mike

James

3/27/2005

1

1/5/1980

102

Robert

Williams

4/25/2007

2

3/5/1983

103

Peter

Paul

3/21/2007

2

4/1/1983

104

Alex

Stuart

2/1/2008

2

11/6/1984

105

Robert

James

1/4/2008

3

12/1/1984

EmployeeNo

Gross

Deduction

NetPay

101

40,000

4,000

36,000

102

80,000

6,000

74,000

103

90,000

7,000

83,000

104

75,000

5,000

70,000

以下 UNION 查询结合了 Employee 和 Salary 表中的 EmployeeNo 值。

SELECT EmployeeNo
FROM
Employee
UNION

SELECT EmployeeNo
FROM
Salary;

执行查询后,会产生以下输出。

EmployeeNo
-----------
   101
   102
   103
   104
   105

UNION ALL

UNION ALL 语句类似于 UNION,它结合了来自多个表的包括重复行在内的结果。

Syntax

以下是 UNION ALL 语句的基本语法。

SELECT col1, col2, col3…
FROM
<table 1>
[WHERE condition]
UNION ALL

SELECT col1, col2, col3…
FROM
<table 2>
[WHERE condition];

Example

以下是 UNION ALL 语句的一个示例。

SELECT EmployeeNo
FROM
Employee
UNION ALL

SELECT EmployeeNo
FROM
Salary;

执行以上查询后,会产生以下输出。你可以看到它还返回了重复项。

 EmployeeNo
-----------
    101
    104
    102
    105
    103
    101
    104
    102
    103

INTERSECT

INTERSECT 命令也用于结合来自多个 SELECT 语句的结果。它返回了在第二个 SELECT 语句中具有对应匹配项的第一个 SELECT 语句中的行。换句话说,它返回了同时存在于这两个 SELECT 语句中的行。

Syntax

以下是 INTERSECT 语句的基本语法。

SELECT col1, col2, col3…
FROM
<table 1>
[WHERE condition]
INTERSECT

SELECT col1, col2, col3…
FROM
<table 2>
[WHERE condition];

Example

以下是 INTERSECT 语句的一个示例。它返回了同时存在于这两个表中的 EmployeeNo 值。

SELECT EmployeeNo
FROM
Employee
INTERSECT

SELECT EmployeeNo
FROM
Salary;

执行以上查询后,会返回以下记录。EmployeeNo 105 被排除在外,因为它不存在于 SALARY 表中。

EmployeeNo
-----------
   101
   104
   102
   103

MINUS/EXCEPT

MINUS/EXCEPT 命令结合了来自多个表的行,并返回存在于第一个 SELECT 中但不存在于第二个 SELECT 中的行。它们都返回相同的结果。

Syntax

以下是 MINUS 语句的基本语法。

SELECT col1, col2, col3…
FROM
<table 1>
[WHERE condition]
MINUS

SELECT col1, col2, col3…
FROM
<table 2>
[WHERE condition];

Example

以下是 MINUS 语句的一个示例。

SELECT EmployeeNo
FROM
Employee
MINUS

SELECT EmployeeNo
FROM
Salary;

执行此查询时,它会返回以下记录。

EmployeeNo
-----------
   105

Teradata - String Manipulation

Teradata 提供了多个函数来处理字符串。这些函数与 ANSI 标准兼容。

Sr.No

String Function & Description

1

*

*Concatenates strings together

2

*SUBSTR*提取字符串的一部分(Teradata 扩展)

3

*SUBSTRING*提取字符串的一部分(ANSI 标准)

4

*INDEX*定位字符串中字符的位置(Teradata 扩展)

5

*POSITION*定位字符串中字符的位置(ANSI 标准)

6

*TRIM*从字符串中修剪空格

7

*UPPER*将字符串转换为大写

8

*LOWER*将字符串转换为小写

Example

下表列出了某些字符串函数及其结果。

String Function

Result

SELECT SUBSTRING(‘warehouse’ FROM 1 FOR 4)

ware

SELECT SUBSTR(‘warehouse’,1,4)

ware

SELECT ‘data’

‘ ‘

‘warehouse’

data warehouse

SELECT UPPER(‘data’)

DATA

SELECT LOWER(‘DATA’)

data

Teradata - Date/Time Functions

本章讨论 Teradata 中提供的日期/时间函数。

Date Storage

日期使用以下公式在内部存储为整数。

((YEAR - 1900) * 10000) + (MONTH * 100) + DAY

您可以使用以下查询检查日期的存储方式。

SELECT CAST(CURRENT_DATE AS INTEGER);

由于日期存储为整数,因此您可以在日期上执行一些算术运算。Teradata 提供可执行这些运算的函数。

EXTRACT

EXTRACT 函数从 DATE 值中摘取日期、月份和年份的部分。该函数也用于从 TIME/TIMESTAMP 值中摘取小时、分钟和秒。

Example

以下示例显示如何从日期和时间戳值中摘取年份、月份、日期、小时、分钟和秒值。

SELECT EXTRACT(YEAR FROM CURRENT_DATE);
EXTRACT(YEAR FROM Date)
-----------------------
        2016
SELECT EXTRACT(MONTH FROM CURRENT_DATE);
EXTRACT(MONTH FROM Date)
------------------------
          1
SELECT EXTRACT(DAY FROM CURRENT_DATE);
EXTRACT(DAY FROM Date)
------------------------
          1

SELECT EXTRACT(HOUR FROM CURRENT_TIMESTAMP);
EXTRACT(HOUR FROM Current TimeStamp(6))
---------------------------------------
                 4
SELECT EXTRACT(MINUTE FROM CURRENT_TIMESTAMP);
EXTRACT(MINUTE FROM Current TimeStamp(6))
-----------------------------------------
                 54
SELECT EXTRACT(SECOND FROM CURRENT_TIMESTAMP);
EXTRACT(SECOND FROM Current TimeStamp(6))
-----------------------------------------
              27.140000

INTERVAL

Teradata 提供 INTERVAL 函数对 DATE 和 TIME 值执行算术运算。有两种类型的 INTERVAL 函数。

Year-Month Interval

  1. YEAR

  2. YEAR TO MONTH

  3. MONTH

Day-Time Interval

  1. DAY

  2. DAY TO HOUR

  3. DAY TO MINUTE

  4. DAY TO SECOND

  5. HOUR

  6. HOUR TO MINUTE

  7. HOUR TO SECOND

  8. MINUTE

  9. MINUTE TO SECOND

  10. SECOND

Example

以下示例将 3 年添加到当前日期。

SELECT CURRENT_DATE, CURRENT_DATE + INTERVAL '03' YEAR;
  Date    (Date+ 3)
--------  ---------
16/01/01   19/01/01

以下示例将 3 年和 01 个月添加到当前日期。

SELECT CURRENT_DATE, CURRENT_DATE + INTERVAL '03-01' YEAR TO MONTH;
 Date     (Date+ 3-01)
--------  ------------
16/01/01    19/02/01

以下示例将 01 天、05 小时和 10 分钟添加到当前时间戳。

SELECT CURRENT_TIMESTAMP,CURRENT_TIMESTAMP + INTERVAL '01 05:10' DAY TO MINUTE;
     Current TimeStamp(6)         (Current TimeStamp(6)+ 1 05:10)
--------------------------------  --------------------------------
2016-01-01 04:57:26.360000+00:00  2016-01-02 10:07:26.360000+00:00

Teradata - Built-in Functions

Teradata 提供内置函数,这是对 SQL 的扩展。以下是常见的内置函数。

Function

Result

SELECT DATE;

Date -------- 16/01/01

SELECT CURRENT_DATE;

Date -------- 16/01/01

SELECT TIME;

Time -------- 04:50:29

SELECT CURRENT_TIME;

Time -------- 04:50:29

SELECT CURRENT_TIMESTAMP;

Current TimeStamp(6) -------------------------------- 2016-01-01 04:51:06.990000+00:00

SELECT DATABASE;

Database ------------------------------ TDUSER

Teradata - Aggregate Functions

Teradata 支持常见的聚合函数。它们可以与 SELECT 语句一起使用。

  1. COUNT − 计算行数

  2. SUM − 对指定列的值求和

  3. MAX − 返回指定列的最大值

  4. MIN − 返回指定列的最小值

  5. AVG − 返回指定列的平均值

Example

请考虑以下 Salary 表。

EmployeeNo

Gross

Deduction

NetPay

101

40,000

4,000

36,000

104

75,000

5,000

70,000

102

80,000

6,000

74,000

105

70,000

4,000

66,000

103

90,000

7,000

83,000

COUNT

以下示例计算 Salary 表中的记录数。

SELECT count(*) from Salary;

  Count(*)
-----------
    5

MAX

以下示例返回最大员工净薪水值。

SELECT max(NetPay) from Salary;
   Maximum(NetPay)
---------------------
       83000

MIN

以下示例从 Salary 表中返回最低员工净薪水值。

SELECT min(NetPay) from Salary;

   Minimum(NetPay)
---------------------
        36000

AVG

以下示例从表中返回员工净薪水值的平均值。

SELECT avg(NetPay) from Salary;

   Average(NetPay)
---------------------
       65800

SUM

以下示例计算 Salary 表所有记录中员工净薪水总和。

SELECT sum(NetPay) from Salary;

   Sum(NetPay)
-----------------
     329000

Teradata - CASE and COALESCE

本章介绍 Teradata 的 CASE 和 COALESCE 函数。

CASE Expression

CASE 表达式针对条件或 WHEN 子句评估每一行,并返回第一次匹配的结果。如果没有匹配项,则返回 ELSE 部分的结果。

Syntax

以下是 CASE 表达式的语法。

CASE <expression>
WHEN <expression> THEN result-1
WHEN <expression> THEN result-2

ELSE
   Result-n
END

Example

考虑以下 Employee 表。

EmployeeNo

FirstName

LastName

JoinedDate

DepartmentNo

BirthDate

101

Mike

James

3/27/2005

1

1/5/1980

102

Robert

Williams

4/25/2007

2

3/5/1983

103

Peter

Paul

3/21/2007

2

4/1/1983

104

Alex

Stuart

2/1/2008

2

11/6/1984

105

Robert

James

1/4/2008

3

12/1/1984

以下示例评估 DepartmentNo 列,如果部门编号为 1,则返回 1;如果部门编号为 3,则返回 2;否则,返回“无效部门”值。

SELECT
   EmployeeNo,
CASE DepartmentNo
   WHEN 1 THEN 'Admin'
   WHEN 2 THEN 'IT'
ELSE 'Invalid Dept'
   END AS Department
FROM Employee;

执行以上查询后,将产生以下输出。

*** Query completed. 5 rows found. 2 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo    Department
-----------   ------------
   101         Admin
   104         IT
   102         IT
   105         Invalid Dept
   103         IT

上面的 CASE 表达式也可以写成以下形式,产生的结果与上面相同。

SELECT
   EmployeeNo,
CASE
   WHEN DepartmentNo = 1 THEN 'Admin'
   WHEN  DepartmentNo = 2 THEN 'IT'
ELSE 'Invalid Dept'
   END AS Department
FROM Employee;

COALESCE

COALESCE 是一个语句,返回表达式中的第一个非空值。如果表达式的所有参数都计算为空值,则它返回 NULL。以下是语法。

Syntax

COALESCE(expression 1, expression 2, ....)

Example

SELECT
   EmployeeNo,
   COALESCE(dept_no, 'Department not found')
FROM
   employee;

NULLIF

NULLIF 语句在参数相等时返回 NULL。

Syntax

以下是 NULLIF 语句的语法。

NULLIF(expression 1, expression 2)

Example

以下示例在 DepartmentNo 等于 3 时返回 NULL。否则,返回 DepartmentNo 值。

SELECT
   EmployeeNo,
   NULLIF(DepartmentNo,3) AS department
FROM Employee;

以上查询返回以下记录。您可以看到员工 105 的部门号为 NULL。

*** Query completed. 5 rows found. 2 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo      department
-----------  ------------------
    101              1
    104              2
    102              2
    105              ?
    103              2

Teradata - Primary Index

主键索引用于指定数据在 Teradata 中所在的位置。它用于指定哪个 AMP 获取数据行。Teradata 中的每个表格都需要定义一个主键索引。如果未定义主键索引,则 Teradata 会自动分配主键索引。主键索引提供了访问数据的最快速方式。主键最多可以有 64 列。

主键索引在创建表格时定义。主键索引有 2 种类型。

  1. Unique Primary Index(UPI)

  2. Non Unique Primary Index(NUPI)

Unique Primary Index (UPI)

如果将表格定义为具有 UPI,则被视为 UPI 的列不应具有任何重复值。如果插入任何重复值,它们将被拒绝。

Create Unique Primary Index

以下示例创建 Salary 表格,其列 EmployeeNo 为唯一主键索引。

CREATE SET TABLE Salary (
   EmployeeNo INTEGER,
   Gross INTEGER,
   Deduction INTEGER,
   NetPay INTEGER
)
UNIQUE PRIMARY INDEX(EmployeeNo);

Non Unique Primary Index (NUPI)

如果将表格定义为具有 NUPI,则被视为 UPI 的列可以接受重复值。

Create Non Unique Primary Index

以下示例创建员工帐户表格,其列 EmployeeNo 为非唯一主键索引。EmployeeNo 定义为非唯一主键索引,因为一名员工可以在表格中拥有多个帐户:一个用于薪资帐户,另一个用于报销帐户。

CREATE SET TABLE Employee _Accounts (
   EmployeeNo INTEGER,
   employee_bank_account_type BYTEINT.
   employee_bank_account_number INTEGER,
   employee_bank_name VARCHAR(30),
   employee_bank_city VARCHAR(30)
)
PRIMARY INDEX(EmployeeNo);

Teradata - Joins

Join 用于将来自多张表的数据记录组合在一起。表是根据这些表中公共栏位/值相连接的。

有不同类型的 Join 可用。

  1. Inner Join

  2. Left Outer Join

  3. Right Outer Join

  4. Full Outer Join

  5. Self Join

  6. Cross Join

  7. Cartesian Production Join

INNER JOIN

Inner Join 组合来自多张表的数据记录,并返回同时存在于这两张表中的值。

Syntax

以下是 INNER JOIN 语句的语法。

SELECT col1, col2, col3….
FROM
Table-1
INNER JOIN
Table-2
ON (col1 = col2)
<WHERE condition>;

Example

考虑以下员工表和薪资表。

EmployeeNo

FirstName

LastName

JoinedDate

DepartmentNo

BirthDate

101

Mike

James

3/27/2005

1

1/5/1980

102

Robert

Williams

4/25/2007

2

3/5/1983

103

Peter

Paul

3/21/2007

2

4/1/1983

104

Alex

Stuart

2/1/2008

2

11/6/1984

105

Robert

James

1/4/2008

3

12/1/1984

EmployeeNo

Gross

Deduction

NetPay

101

40,000

4,000

36,000

102

80,000

6,000

74,000

103

90,000

7,000

83,000

104

75,000

5,000

70,000

以下查询在公共栏位 EmployeeNo 上连接 Employee 表和 Salary 表。每个表都被赋予别名 A 和 B,并且栏位使用正确的别名进行引用。

SELECT A.EmployeeNo, A.DepartmentNo, B.NetPay
FROM
Employee A
INNER JOIN
Salary B
ON (A.EmployeeNo = B. EmployeeNo);

当执行以上查询时,将会返回以下记录。员工 105 未包含在结果中,因为它在 Salary 表中没有匹配的记录。

*** Query completed. 4 rows found. 3 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo   DepartmentNo     NetPay
-----------  ------------   -----------
    101           1            36000
    102           2            74000
    103           2            83000
    104           2            70000

OUTER JOIN

LEFT OUTER JOIN 和 RIGHT OUTER JOIN 也合并来自多张表的结果。

  1. LEFT OUTER JOIN 返回来自左表的全部记录,并且仅返回来自右表的匹配记录。

  2. RIGHT OUTER JOIN 返回来自右表的全部记录,并且仅返回来自左表的匹配记录。

  3. FULL OUTER JOIN 组合来自 LEFT OUTER 和 RIGHT OUTER JOIN 的结果。它返回来自联结表的匹配记录和不匹配记录。

Syntax

以下为 OUTER JOIN 语句的语法。你需要使用 LEFT OUTER JOIN、RIGHT OUTER JOIN 或 FULL OUTER JOIN 中的一个选项。

SELECT col1, col2, col3….
FROM
Table-1
LEFT OUTER JOIN/RIGHT OUTER JOIN/FULL OUTER JOIN
Table-2
ON (col1 = col2)
<WHERE condition>;

Example

考虑以下 LEFT OUTER JOIN 查询示例。它返回 Employee 表中的所有记录以及 Salary 表中的匹配记录。

SELECT A.EmployeeNo, A.DepartmentNo, B.NetPay
FROM
Employee A
LEFT OUTER JOIN
Salary B
ON (A.EmployeeNo = B. EmployeeNo)
ORDER BY A.EmployeeNo;

当执行以上查询时,将生成以下输出。对于员工 105,NetPay 值为 NULL,因为它在 Salary 表中没有匹配的记录。

*** Query completed. 5 rows found. 3 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo  DepartmentNo     NetPay
-----------  ------------   -----------
    101           1           36000
    102           2           74000
    103           2           83000
    104           2           70000
    105           3             ?

CROSS JOIN

Cross Join 将左表中的每行与右表中的每行进行连接。

Syntax

以下是 CROSS JOIN 语句的语法。

SELECT A.EmployeeNo, A.DepartmentNo, B.EmployeeNo,B.NetPay
FROM
Employee A
CROSS JOIN
Salary B
WHERE A.EmployeeNo = 101
ORDER BY B.EmployeeNo;

执行上述查询时,将得到以下输出。将 Employee 表中的员工编号 101 与 Salary 表中的每一条记录联接。

*** Query completed. 4 rows found. 4 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo  DepartmentNo   EmployeeNo    NetPay
-----------  ------------  -----------  -----------
    101           1            101         36000
    101           1            104         70000
    101           1            102         74000
    101           1            103         83000

Teradata - SubQueries

子查询基于其他表中的值从一个表中返回记录。它是另一个查询中的 SELECT 查询。称为内部查询的 SELECT 查询首先执行,而结果则由外部查询使用。其一些显著特征:

  1. 查询可以有多个子查询,并且子查询可以包含其他子查询。

  2. 子查询不返回重复的记录。

  3. 如果子查询仅返回一个值,则可以使用 = 运算符将其与外部查询一起使用。如果它返回多个值,则可以使用 IN 或 NOT IN。

Syntax

以下是子查询的通用语法。

SELECT col1, col2, col3,…
FROM
Outer Table
WHERE col1 OPERATOR ( Inner SELECT Query);

Example

考虑以下 Salary 表格。

EmployeeNo

Gross

Deduction

NetPay

101

40,000

4,000

36,000

102

80,000

6,000

74,000

103

90,000

7,000

83,000

104

75,000

5,000

70,000

以下查询标识出具有最高工资的员工编号。内部 SELECT 执行聚合函数以返回最大的 NetPay 值,而外部 SELECT 查询使用此值返回具有此值的员工记录。

SELECT EmployeeNo, NetPay
FROM Salary
WHERE NetPay =
(SELECT MAX(NetPay)
FROM Salary);

执行此查询时,将得到以下输出。

*** Query completed. One row found. 2 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo     NetPay
-----------  -----------
    103         83000

Teradata - Table Types

Teradata 支持以下表格类型来保存临时数据。

  1. Derived Table

  2. Volatile Table

  3. Global Temporary Table

Derived Table

导出表在查询中创建、使用和删除。它们用于在查询中存储中间结果。

Example

以下示例使用工资超过 75000 的员工记录构建了导出表 EmpSal。

SELECT
Emp.EmployeeNo,
Emp.FirstName,
Empsal.NetPay
FROM
Employee Emp,
(select EmployeeNo , NetPay
from Salary
where NetPay >= 75000) Empsal
where Emp.EmployeeNo = Empsal.EmployeeNo;

当执行以上查询时,它将返回工资超过 75000 的员工。

*** Query completed. One row found. 3 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo            FirstName               NetPay
-----------  ------------------------------  -----------
    103                  Peter                 83000

Volatile Table

易失表在用户会话中创建、使用和删除。它们的定义未存储在数据字典中。它们保存查询中经常使用的中间数据。以下是语法。

Syntax

CREATE [SET|MULTISET] VOALTILE TABLE tablename
<table definitions>
<column definitions>
<index definitions>
ON COMMIT [DELETE|PRESERVE] ROWS

Example

CREATE VOLATILE TABLE dept_stat (
   dept_no INTEGER,
   avg_salary INTEGER,
   max_salary INTEGER,
   min_salary INTEGER
)
PRIMARY INDEX(dept_no)
ON COMMIT PRESERVE ROWS;

执行以上查询后,将产生以下输出。

*** Table has been created.
*** Total elapsed time was 1 second.

Global Temporary Table

全局临时表的定义存储在数据字典中,并且可以在许多用户/会话中使用它们。但加载到全局临时表中的数据仅在会话期间保留。每个会话最多可以实现 2000 个全局临时表。以下是语法。

Syntax

CREATE [SET|MULTISET] GLOBAL TEMPORARY TABLE tablename
<table definitions>
<column definitions>
<index definitions>

Example

CREATE SET GLOBAL TEMPORARY TABLE dept_stat (
   dept_no INTEGER,
   avg_salary INTEGER,
   max_salary INTEGER,
   min_salary INTEGER
)
PRIMARY INDEX(dept_no);

执行以上查询后,将产生以下输出。

*** Table has been created.
*** Total elapsed time was 1 second.

Teradata - Space Concepts

Teradata 中有三种类型的空间可用。

Permanent Space

永久空间是用户/数据库可用于保存数据行的最大可用空间。永久表、日记、回退表和辅助索引子表使用永久空间。

永久空间不会预先分配给数据库/用户。它们仅被定义为数据库/用户可以使用的最大空间量。永久空间的数量将除以 AMP 的数量。每当 AMP 限制超过时,就会生成一个错误消息。

Spool Space

池空间是未使用的永久空间,系统使用它来保留 SQL 查询的中间结果。没有池空间的用户无法执行任何查询。

类似永久空间,池空间定义用户可以使用的最大空间量。池空间将除以 AMP 的数量。每当 AMP 限制超过时,用户都会收到池空间错误。

Temp Space

临时空间是未使用的永久空间,由全局临时表使用。临时空间也会除以 AMP 的数量。

Teradata - Secondary Index

表只能包含一个主键索引。更常见的是,您将遇到表包含其他列的情况,其中使用经常访问数据。Teradata 将对这些查询执行全表扫描。辅助索引解决了此问题。

辅助索引是访问数据的替代路径。主键索引与辅助索引之间存在一些差异。

  1. 辅助索引不参与数据分布。

  2. 辅助索引值存储在子表中。这些表内置于所有 AMP 中。

  3. Secondary indexes are optional.

  4. 它们可以在创建表时或创建表后创建。

  5. 由于构建子表并使用它,它们占用额外空间,并且由于需要为每一行更新子表,它们还需要维护。

有两种类型的二级索引 -

  1. Unique Secondary Index (USI)

  2. Non-Unique Secondary Index (NUSI)

Unique Secondary Index (USI)

唯一二级索引仅允许定义为 USI 的列的唯一值。通过 USI 访问行是两 amp 操作。

Create Unique Secondary Index

以下示例在 employee 表的 EmployeeNo 列上创建 USI。

CREATE UNIQUE INDEX(EmployeeNo) on employee;

Non Unique Secondary Index (NUSI)

非唯一二级索引允许定义为 NUSI 的列的重复值。通过 NUSI 访问行是全部-amp 操作。

Create Non Unique Secondary Index

以下示例在 employee 表的 FirstName 上创建 NUSI。

CREATE INDEX(FirstName) on Employee;

Teradata - Statistics

Teradata 优化器会针对每个 SQL 查询提出执行策略。此执行策略基于在 SQL 查询所用表中收集的统计信息。使用 COLLECT STATISTICS 命令收集表的统计信息。优化器需要环境信息和数据人口统计信息来提出最佳执行策略。

Environment Information

  1. 节点、AMP 和 CPU 的数量

  2. Amount of memory

Data Demographics

  1. Number of rows

  2. Row size

  3. 表中的值范围

  4. 每个值的行数

  5. Number of Nulls

有三种方法可用于收集表中的统计信息。

  1. Random AMP Sampling

  2. Full statistics collection

  3. Using SAMPLE option

Collecting Statistics

COLLECT STATISTICS 命令用于收集表中的统计信息。

Syntax

以下是收集表中的统计信息的语法。

COLLECT [SUMMARY] STATISTICS
INDEX (indexname) COLUMN (columnname)
ON <tablename>;

Example

以下示例收集 Employee 表的 EmployeeNo 列中的统计信息。

COLLECT STATISTICS COLUMN(EmployeeNo) ON Employee;

执行以上查询后,将产生以下输出。

*** Update completed. 2 rows changed.
*** Total elapsed time was 1 second.

Viewing Statistics

您可以使用 HELP STATISTICS 命令查看收集到的统计信息。

Syntax

以下是查看所收集统计信息的语法。

HELP STATISTICS <tablename>;

Example

以下是查看 Employee 表中收集到的统计信息的示例。

HELP STATISTICS employee;

当执行上面的查询时,会生成以下结果。

  Date       Time      Unique Values           Column Names
--------   -------- -------------------- -----------------------
16/01/01   08:07:04         5                       *
16/01/01   07:24:16         3                   DepartmentNo
16/01/01   08:07:04         5                   EmployeeNo

Teradata - Compression

压缩用于减少表格使用的存储空间。在 Teradata 中,压缩可以压缩 255 个不同的值,包括 NULL。由于存储减少,因此 Teradata 可以在一个块中存储更多的记录。由于每个 I/O 操作可以处理每个块中的更多行,因此这将改善查询响应时间。可以在创建表格时使用 CREATE TABLE 添加压缩,或在创建表格后使用 ALTER TABLE 命令添加压缩。

Limitations

  1. 每列最多能压缩 255 个值。

  2. 主索引列不能压缩。

  3. 不稳定表也不能压缩。

Multi-Value Compression (MVC)

下表将字段 DepatmentNo 压缩为值 1、2 和 3。当压缩应用于某一列时,该列的值不会与该行存储在一起。而是这些值存储在每个 AMP 的表头中,并且只添加表示值到行中的存在位。

CREATE SET TABLE employee (
   EmployeeNo integer,
   FirstName CHAR(30),
   LastName CHAR(30),
   BirthDate DATE FORMAT 'YYYY-MM-DD-',
   JoinedDate DATE FORMAT 'YYYY-MM-DD-',
   employee_gender CHAR(1),
   DepartmentNo CHAR(02) COMPRESS(1,2,3)
)
UNIQUE PRIMARY INDEX(EmployeeNo);

多值压缩可用于处理包含有限值的大表中的列。

Teradata - Explain

EXPLAIN 命令以英语返回解析引擎的执行计划。它可以与任何 SQL 语句一起使用,但不能与另一个 EXPLAIN 命令一起使用。当查询以 EXPLAIN 命令开头时,解析引擎的执行计划将返回给用户,而不是 AMP。

Examples of EXPLAIN

考虑以下定义的 Employee 表。

CREATE SET TABLE EMPLOYEE,FALLBACK (
   EmployeeNo INTEGER,
   FirstName VARCHAR(30),
   LastName VARCHAR(30),
   DOB DATE FORMAT 'YYYY-MM-DD',
   JoinedDate DATE FORMAT 'YYYY-MM-DD',
   DepartmentNo BYTEINT
)
UNIQUE PRIMARY INDEX ( EmployeeNo );

下面给出了一些 EXPLAIN 计划示例。

Full Table Scan (FTS)

当 SELECT 语句中未指定条件时,优化器可能会选择使用全表扫描,在该扫描中将访问表中的每一行。

Example

以下是优化器可能选择 FTS 的示例查询。

EXPLAIN SELECT * FROM employee;

当执行以上查询时,它将生成以下输出。可以看出,优化器选择访问所有 AMP 和 AMP 中的所有行。

1) First, we lock a distinct TDUSER."pseudo table" for read on a
   RowHash to prevent global deadlock for TDUSER.employee.
2) Next, we lock TDUSER.employee for read.
3) We do an all-AMPs RETRIEVE step from TDUSER.employee by way of an
   all-rows scan with no residual conditions into Spool 1
   (group_amps), which is built locally on the AMPs.  The size of
   Spool 1 is estimated with low confidence to be 2 rows (116 bytes).
   The estimated time for this step is 0.03 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
   in processing the request.
→ The contents of Spool 1 are sent back to the user as the result of
   statement 1.  The total estimated time is 0.03 seconds.

Unique Primary Index

当使用唯一的主索引访问行时,则是一个 AMP 操作。

EXPLAIN SELECT * FROM employee WHERE EmployeeNo = 101;

当执行以上查询时,它将生成以下输出。可以看到,这是一个单 AMP 检索,并且优化器正在使用唯一的主索引来访问行。

1) First, we do a single-AMP RETRIEVE step from TDUSER.employee by
   way of the unique primary index "TDUSER.employee.EmployeeNo = 101"
   with no residual conditions. The estimated time for this step is
   0.01 seconds.
→ The row is sent directly back to the user as the result of
   statement 1.  The total estimated time is 0.01 seconds.

Unique Secondary Index

当使用唯一辅助索引访问行时,这是一个两安操作。

Example

查看如下定义的表“薪资”。

CREATE SET TABLE SALARY,FALLBACK (
   EmployeeNo INTEGER,
   Gross INTEGER,
   Deduction INTEGER,
   NetPay INTEGER
)
PRIMARY INDEX ( EmployeeNo )
UNIQUE INDEX (EmployeeNo);

查看以下 SELECT 语句。

EXPLAIN SELECT * FROM Salary WHERE EmployeeNo = 101;

当执行上述查询时,会生成以下输出。正如可以看到的那样,优化器使用唯一的辅助索引在两安操作中检索行。

1) First, we do a two-AMP RETRIEVE step from TDUSER.Salary
   by way of unique index # 4 "TDUSER.Salary.EmployeeNo =
   101" with no residual conditions.  The estimated time for this
   step is 0.01 seconds.
→ The row is sent directly back to the user as the result of
   statement 1.  The total estimated time is 0.01 seconds.

Additional Terms

以下是 EXPLAIN 计划中常见的术语列表。

…​ (Last Use) …

不再需要暂存文件,并且在完成此步骤时将释放该文件。

…​ with no residual conditions …

所有适用的条件都已应用于行。

…​ END TRANSACTION …

释放事务锁,并且提交更改。

…​ eliminating duplicate rows …​

仅在暂存文件中存在重复行,不存在集合表中。执行 DISTINCT 操作。

…​ by way of a traversal of index #n extracting row ids only …

构建一个包含在辅助索引(索引 #n)中找到的行 ID 的暂存文件。

…​ we do a SMS (set manipulation step) …

使用 UNION、MINUS 或 INTERSECT 运算符组合行。

…​ which is redistributed by hash code to all AMPs.

在准备联接时重新分发数据。

…​ which is duplicated on all AMPs.

复制更小表(根据 SPOOL)中数据以准备进行联接。

…​ (one_AMP) or (group_AMPs)

指明将使用一个 AMP 或 AMP 子集而不是全部 AMP。

Teradata - Hashing Algorithm

行是根据主键值分配给特定 AMP 的。Teradata 使用哈希算法来确定哪一个 AMP 获取行。

以下是有关哈希算法的高级图表。

hashing algorithm

以下是插入数据的步骤。

  1. 客户端提交查询。

  2. 解析器接收查询并将记录的 PI 值传递给哈希算法。

  3. 哈希算法对主键值进行哈希处理,并返回一个称为行哈希的 32 位数字。

  4. 行哈希的高位(前 16 位)用于标识哈希映射条目。哈希映射包含一个 AMP #。哈希映射是一个包含特定 AMP # 的存储桶数组。

  5. BYNET 将数据发送到已识别的 AMP。

  6. AMP 使用 32 位行哈希定位磁盘中的行。

  7. 如果存在具有相同行哈希的任何记录,则它会增加唯一性 ID(一个 32 位数字)。对于新的行哈希,唯一性 ID 被分配为 1,并且每当插入具有相同行哈希的记录时都会增加 1。

  8. 行哈希和唯一性 ID 的组合称为行 ID。

  9. 行 ID 为磁盘中的每条记录添加前缀。

  10. AMP 中的每一行表格都按其行 ID 逻辑排序。

How Tables are Stored

表格按其行 ID(行哈希 + 唯一性 ID)排序,然后存储在 AMP 中。行 ID 与每行数据一起存储。

Row Hash

Uniqueness ID

EmployeeNo

FirstName

LastName

2A01 2611

0000 0001

101

Mike

James

2A01 2612

0000 0001

104

Alex

Stuart

2A01 2613

0000 0001

102

Robert

Williams

2A01 2614

0000 0001

105

Robert

James

2A01 2615

0000 0001

103

Peter

Paul

Teradata - JOIN Index

JOIN INDEX 是物化视图。其定义永久存储,每当关联索引中引用的基础表更新时数据都会更新。JOIN INDEX 可能包含一个或多个表,并且还包含预聚合数据。连接索引主要用于提高性能。

有不同类型的 join 索引可用。

  1. 单表连接索引 (STJI)

  2. 多表连接索引 (MTJI)

  3. Aggregated Join Index (AJI)

Single Table Join Index

单表连接索引允许基于不同于基础表的主索引列对大表进行分区。

Syntax

以下是 JOIN INDEX 的语法。

CREATE JOIN INDEX <index name>
AS
<SELECT Query>
<Index Definition>;

Example

考虑以下 Employee 和 Salary 表。

CREATE SET TABLE EMPLOYEE,FALLBACK (
   EmployeeNo INTEGER,
   FirstName VARCHAR(30) ,
   LastName VARCHAR(30) ,
   DOB DATE FORMAT 'YYYY-MM-DD',
   JoinedDate DATE FORMAT 'YYYY-MM-DD',
   DepartmentNo BYTEINT
)
UNIQUE PRIMARY INDEX ( EmployeeNo );

CREATE SET TABLE SALARY,FALLBACK (
   EmployeeNo INTEGER,
   Gross INTEGER,
   Deduction INTEGER,
   NetPay INTEGER
)
PRIMARY INDEX ( EmployeeNo )
UNIQUE INDEX (EmployeeNo);

以下是一个示例,在 Employee 表上创建名为 Employee_JI 的连接索引。

CREATE JOIN INDEX Employee_JI
AS
SELECT EmployeeNo,FirstName,LastName,
BirthDate,JoinedDate,DepartmentNo
FROM Employee
PRIMARY INDEX(FirstName);

如果用户提交一个带有 EmployeeNo 的 WHERE 子句的查询,那么系统将使用唯一主索引对 Employee 表进行查询。如果用户使用 employee_name 对 employee 表进行查询,那么系统可能会使用 employee_name 访问关联索引 Employee_JI。连接索引的行在 employee_name 列上进行哈希处理。如果没有定义连接索引,并且 employee_name 未定义为二级索引,那么系统将执行全表扫描以访问耗时的行。

您可以运行以下 EXPLAIN 计划并验证优化器计划。在以下示例中,您会看到优化器在使用 Employee_Name 列查询表时使用连接索引而不是基础 Employee 表。

EXPLAIN SELECT * FROM EMPLOYEE WHERE FirstName='Mike';
*** Help information returned. 8 rows.
*** Total elapsed time was 1 second.
Explanation
------------------------------------------------------------------------
   1) First, we do a single-AMP RETRIEVE step from EMPLOYEE_JI by
      way of the primary index "EMPLOYEE_JI.FirstName = 'Mike'"
      with no residual conditions into Spool 1 (one-amp), which is built
      locally on that AMP.  The size of Spool 1 is estimated with low
      confidence to be 2 rows (232 bytes).  The estimated time for this
      step is 0.02 seconds.
   → The contents of Spool 1 are sent back to the user as the result of
      statement 1.  The total estimated time is 0.02 seconds.

Multi Table Join Index

多表连接索引通过连接多张表来创建。多表连接索引可用于存储常用连接表的 result 集,以提高性能。

Example

以下示例通过连接 Employee 和 Salary 表创建名为 Employee_Salary_JI 的 JOIN INDEX。

CREATE JOIN INDEX Employee_Salary_JI
AS
SELECT a.EmployeeNo,a.FirstName,a.LastName,
a.BirthDate,a.JoinedDate,a.DepartmentNo,b.Gross,b.Deduction,b.NetPay
FROM Employee a
INNER JOIN Salary b
ON(a.EmployeeNo = b.EmployeeNo)
PRIMARY INDEX(FirstName);

每当更新基础表 Employee 或 Salary 时,连接索引 Employee_Salary_JI 也会自动更新。如果您正在运行一个连接 Employee 和 Salary 表的查询,那么优化器可能会选择直接从 Employee_Salary_JI 访问数据,而不是连接表。可以对查询使用 EXPLAIN 计划来验证优化器是否会选择基础表或连接索引。

Aggregate Join Index

如果某个表总是在某些列上聚合,那么可以在表上定义聚合连接索引来提升性能。聚合连接索引的一个限制是它仅支持 SUM 和 COUNT 函数。

Example

在以下示例中,员工和薪水连接起来,从而按部门识别总薪水。

CREATE JOIN INDEX Employee_Salary_JI
AS
SELECT a.DepartmentNo,SUM(b.NetPay) AS TotalPay
FROM Employee a
INNER JOIN Salary b
ON(a.EmployeeNo = b.EmployeeNo)
GROUP BY a.DepartmentNo
Primary Index(DepartmentNo);

Teradata - Views

视图是通过查询构建的数据库对象。视图可以使用单个表或通过连接使用多个表构建。其定义永久存储在数据字典中,但它们不会存储数据的副本。视图的数据是动态构建的。

视图可能包含表的子行集或表的子列集。

Create a View

使用 CREATE VIEW 语句创建视图。

Syntax

以下是创建视图的语法。

CREATE/REPLACE VIEW <viewname>
AS
<select query>;

Example

考虑以下 Employee 表。

EmployeeNo

FirstName

LastName

BirthDate

101

Mike

James

1/5/1980

104

Alex

Stuart

11/6/1984

102

Robert

Williams

3/5/1983

105

Robert

James

12/1/1984

103

Peter

Paul

4/1/1983

以下示例在 Employee 表上创建了一个视图。

CREATE VIEW Employee_View
AS
SELECT
EmployeeNo,
FirstName,
LastName,
FROM
Employee;

Using Views

您可以使用常规 SELECT 语句从视图中检索数据。

Example

以下示例从 Employee_View 中检索记录;

SELECT EmployeeNo, FirstName, LastName FROM Employee_View;

执行以上查询后,将产生以下输出。

*** Query completed. 5 rows found. 3 columns returned.
*** Total elapsed time was 1 second.
 EmployeeNo            FirstName                       LastName
-----------  ------------------------------  ---------------------------
    101                  Mike                           James
    104                  Alex                           Stuart
    102                  Robert                         Williams
    105                  Robert                         James
    103                  Peter                          Paul

Modifying Views

可以使用 REPLACE VIEW 语句修改现有视图。

以下是修改视图的语法。

REPLACE VIEW <viewname>
AS
<select query>;

Example

以下示例修改视图 Employee_View 以添加额外列。

REPLACE VIEW Employee_View
AS
SELECT
EmployeeNo,
FirstName,
BirthDate,
JoinedDate
DepartmentNo
FROM
Employee;

Drop View

可以使用 DROP VIEW 语句删除现有视图。

Syntax

以下是 DROP VIEW 的语法。

DROP VIEW <viewname>;

Example

以下是删除视图 Employee_View 的示例。

DROP VIEW Employee_View;

Advantages of Views

  1. 视图通过限制表的行或列提供额外的安全级别。

  2. 可以仅授予用户对视图的访问权限,而不是授予对基础表的访问权限。

  3. 通过使用视图预连接多个表,简化了多个表的使用。

Teradata - Macros

宏是一组 SQL 语句,它们通过调用宏名称来存储和执行。宏的定义存储在数据字典中。用户只需要 EXEC 权限来执行宏。用户不需要对宏中使用的数据库对象有单独的权限。宏语句作为单个事务执行。如果宏中的一个 SQL 语句失败,那么所有语句都会回滚。宏可以接受参数。宏可以包含 DDL 语句,但该语句应为宏中的最后一条语句。

Create Macros

使用 CREATE MACRO 语句创建宏。

Syntax

以下为 CREATE MACRO 命令的通用语法。

CREATE MACRO <macroname> [(parameter1, parameter2,...)] (
   <sql statements>
);

Example

考虑以下 Employee 表。

EmployeeNo

FirstName

LastName

BirthDate

101

Mike

James

1/5/1980

104

Alex

Stuart

11/6/1984

102

Robert

Williams

3/5/1983

105

Robert

James

12/1/1984

103

Peter

Paul

4/1/1983

以下示例创建了一个名为 Get_Emp 的宏。它包含一个 select 语句以从员工表中检索记录。

CREATE MACRO Get_Emp AS (
   SELECT
   EmployeeNo,
   FirstName,
   LastName
   FROM
   employee
   ORDER BY EmployeeNo;
);

Executing Macros

使用 EXEC 命令执行宏。

Syntax

以下为 EXECUTE MACRO 命令的语法。

EXEC <macroname>;

Example

以下示例执行名为 Get_Emp 的宏;当执行以下命令时,它会从员工表中检索所有记录。

EXEC Get_Emp;
*** Query completed. 5 rows found. 3 columns returned.
*** Total elapsed time was 1 second.
EmployeeNo             FirstName                      LastName
-----------  ------------------------------  ---------------------------
   101                  Mike                          James
   102                  Robert                        Williams
   103                  Peter                         Paul
   104                  Alex                          Stuart
   105                  Robert                        James

Parameterized Macros

Teradata 宏可以接受参数。在宏中,这些参数用 ;(分号)引用。

以下是接受参数的宏示例。

CREATE MACRO Get_Emp_Salary(EmployeeNo INTEGER) AS (
   SELECT
   EmployeeNo,
   NetPay
   FROM
   Salary
   WHERE EmployeeNo = :EmployeeNo;
);

Executing Parameterized Macros

使用 EXEC 命令执行宏。您需要 EXEC 权限才能执行宏。

Syntax

以下为 EXECUTE MACRO 语句的语法。

EXEC <macroname>(value);

Example

以下示例执行名为 Get_Emp 的宏;它接受员工编号作为参数,并为该员工从员工表中提取记录。

EXEC Get_Emp_Salary(101);
*** Query completed. One row found. 2 columns returned.
*** Total elapsed time was 1 second.

EmployeeNo      NetPay
-----------  ------------
   101           36000

Teradata - Stored Procedure

存储过程包含一组 SQL 语句和过程语句。它们可能仅包含过程语句。存储过程的定义存储在数据库中,并且参数存储在数据字典表中。

Advantages

  1. 存储过程减少了客户端和服务器之间的网络负载。

  2. 提供了更好的安全性,因为数据通过存储过程访问,而不是直接访问。

  3. 给出了更好的维护,因为业务逻辑已在服务器中进行测试并存储。

Creating Procedure

存储过程使用 CREATE PROCEDURE 语句创建。

Syntax

以下是 CREATE PROCEDURE 语句的通用语法。

CREATE PROCEDURE <procedurename> ( [parameter 1 data type, parameter 2 data type..] )
BEGIN
   <SQL or SPL statements>;
END;

Example

请考虑以下 Salary 表。

EmployeeNo

Gross

Deduction

NetPay

101

40,000

4,000

36,000

102

80,000

6,000

74,000

103

90,000

7,000

83,000

104

75,000

5,000

70,000

以下示例创建了一个名为 InsertSalary 的存储过程以接受值并将其插入 Salary 表中。

CREATE PROCEDURE InsertSalary (
   IN in_EmployeeNo INTEGER, IN in_Gross INTEGER,
   IN in_Deduction INTEGER, IN in_NetPay INTEGER
)
BEGIN
   INSERT INTO Salary (
      EmployeeNo,
      Gross,
      Deduction,
      NetPay
   )
   VALUES (
      :in_EmployeeNo,
      :in_Gross,
      :in_Deduction,
      :in_NetPay
   );
END;

Executing Procedures

存储过程使用 CALL 语句执行。

Syntax

以下是 CALL 语句的通用语法。

CALL <procedure name> [(parameter values)];

Example

以下示例调用存储过程 InsertSalary 并将记录插入 Salary 表中。

CALL InsertSalary(105,20000,2000,18000);

一旦执行以上查询,它将生成以下输出,您可以在 Salary 表中看到已插入的行。

EmployeeNo

Gross

Deduction

NetPay

101

40,000

4,000

36,000

102

80,000

6,000

74,000

103

90,000

7,000

83,000

104

75,000

5,000

70,000

105

20,000

2,000

18,000

Teradata - JOIN strategies

本章讨论 Teradata 中可用的各种 JOIN 策略。

Join Methods

Teradata 使用不同的连接方法来执行连接操作。一些常用的连接方法包括:

  1. Merge Join

  2. Nested Join

  3. Product Join

Merge Join

当连接基于相等条件时,将执行 Merge Join 方法。Merge Join 要求连接的行位于同一 AMP 上。行是根据其行哈希连接的。Merge Join 使用不同的连接策略将行带到同一个 AMP。

Strategy

如果连接列是相应表的初级索引,那么连接行已经位于同一个 AMP 上。在这种情况下,不需要分配。

考虑以下员工和薪水表。

CREATE SET TABLE EMPLOYEE,FALLBACK (
   EmployeeNo INTEGER,
   FirstName VARCHAR(30) ,
   LastName VARCHAR(30) ,
   DOB DATE FORMAT 'YYYY-MM-DD',
   JoinedDate DATE FORMAT 'YYYY-MM-DD',
   DepartmentNo BYTEINT
)
UNIQUE PRIMARY INDEX ( EmployeeNo );
CREATE SET TABLE Salary (
   EmployeeNo INTEGER,
   Gross INTEGER,
   Deduction INTEGER,
   NetPay INTEGER
)
UNIQUE PRIMARY INDEX(EmployeeNo);

当这两个表按 EmployeeNo 列连接时,则不会发生重新分配,因为 EmployeeNo 是被连接的两个表的初级索引。

Strategy

考虑以下员工和部门表。

CREATE SET TABLE EMPLOYEE,FALLBACK (
   EmployeeNo INTEGER,
   FirstName VARCHAR(30) ,
   LastName VARCHAR(30) ,
   DOB DATE FORMAT 'YYYY-MM-DD',
   JoinedDate DATE FORMAT 'YYYY-MM-DD',
   DepartmentNo BYTEINT
)
UNIQUE PRIMARY INDEX ( EmployeeNo );
CREATE SET TABLE DEPARTMENT,FALLBACK (
   DepartmentNo BYTEINT,
   DepartmentName CHAR(15)
)
UNIQUE PRIMARY INDEX ( DepartmentNo );

如果这两个表按 DeparmentNo 列连接,那么需要重新分配这些行,因为 DepartmentNo 是一个表中的初级索引,而另一个表中的非初级索引。在此场景中,连接行可能不在同一个 AMP 上。在这种情况下,Teradata 可能会在 DepartmentNo 列上重新分配员工表。

Strategy

对于上面的员工和部门表,如果部门表大小较小,Teradata 可能会在所有 AMP 上复制部门表。

Nested Join

Nested Join 并不使用所有 AMP。对于 Nested Join 来说,一个条件应该是对一个表的唯一初级索引的相等,然后将此列连接到另一个表上的任何索引。

在此情况下,系统将使用一个表唯一初级索引获取一行,并使用该行哈希从其他表获取匹配的记录。Nested join 是所有连接方法中最有效的。

Product Join

Product Join 将一个表中每个符合条件的行与另一个表中每个符合条件的行进行比较。由于以下一些因素,可能会发生 Product join:

  1. Where condition is missing.

  2. 连接条件不基于相等条件。

  3. 表别名不正确。

  4. Multiple join conditions.

Teradata - Partitioned Primary Index

分区主索引 (PPI) 是一种索引机制,可用于提高某些查询的性能。当行插入表中时,它们会存储在 AMP 中,并按其行哈希顺序排列。当使用 PPI 定义表时,行会按其分区号排序。在每个分区内,它们会按行哈希排列。行会根据定义的分区表达式分配给分区。

Advantages

  1. 避免对某些查询进行全表扫描。

  2. 避免使用需要其它物理结构和其它 I/O 维护的二级索引。

  3. 快速访问大表的子集。

  4. 快速删除旧数据并添加新数据。

Example

考虑具有订单号为主索引的如下订单表。

StoreNo

OrderNo

OrderDate

OrderTotal

101

7501

2015-10-01

900

101

7502

2015-10-02

1,200

102

7503

2015-10-02

3,000

102

7504

2015-10-03

2,454

101

7505

2015-10-03

1201

103

7506

2015-10-04

2,454

101

7507

2015-10-05

1201

101

7508

2015-10-05

1201

假设记录如以下表格所示在 AMP 之间进行分配。记录存储在 AMP 中,根据其行哈希进行排序。

**

RowHash

OrderNo

OrderDate

1

7505

2015-10-03

2

7504

2015-10-03

3

7501

2015-10-01

4

7508

2015-10-05

**

RowHash

OrderNo

OrderDate

1

7507

2015-10-05

2

7502

2015-10-02

3

7506

2015-10-04

4

7503

2015-10-02

如果您运行一个查询以提取某个特定日期的订单,则优化器可能会选择使用全表扫描,然后访问 AMP 中的所有记录。为了避免这种情况,您可以将订单日期定义为分区主索引。当行插入订单表时,它们按订单日期分区。它们将在每个分区中按其行哈希进行排序。

以下数据显示了如果按订单日期分区,记录如何存储在 AMP 中。如果运行一个查询以按订单日期访问记录,则只会访问包含特定订单记录的分区。

**

Partition

RowHash

OrderNo

OrderDate

0

3

7501

2015-10-01

1

1

7505

2015-10-03

1

2

7504

2015-10-03

2

4

7508

2015-10-05

**

Partition

RowHash

OrderNo

OrderDate

0

2

7502

2015-10-02

0

4

7503

2015-10-02

1

3

7506

2015-10-04

2

1

7507

2015-10-05

以下是一个带分区主索引创建表的示例。PARTITION BY 子句用于定义分区。

CREATE SET TABLE Orders (
   StoreNo SMALLINT,
   OrderNo INTEGER,
   OrderDate DATE FORMAT 'YYYY-MM-DD',
   OrderTotal INTEGER
)
PRIMARY INDEX(OrderNo)
PARTITION BY RANGE_N  (
   OrderDate BETWEEN DATE '2010-01-01' AND '2016-12-31' EACH INTERVAL '1' DAY
);

在上述示例中,该表按 OrderDate 列分区。每一天将会有一个单独的分区。

Teradata - OLAP Functions

OLAP 函数与聚合函数类似,只不过聚合函数仅返回一个值,而 OLAP 函数将提供各个行和聚合。

Syntax

以下是 OLAP 函数的一般语法。

<aggregate function> OVER
([PARTITION BY] [ORDER BY columnname][ROWS BETWEEN
UNBOUDED PRECEDING AND UNBOUNDED FOLLOWING)

聚合函数可以是 SUM、COUNT、MAX、MIN、AVG。

Example

考虑以下 Salary 表格。

EmployeeNo

Gross

Deduction

NetPay

101

40,000

4,000

36,000

102

80,000

6,000

74,000

103

90,000

7,000

83,000

104

75,000

5,000

70,000

以下是一个在 Salary 表格上查找 NetPay 的累积和或运行总和的示例。记录按 EmployeeNo 排序,并在 NetPay 列上计算累积和。

SELECT
EmployeeNo, NetPay,
SUM(Netpay) OVER(ORDER BY EmployeeNo ROWS
UNBOUNDED PRECEDING) as TotalSalary
FROM Salary;

执行以上查询后,将产生以下输出。

EmployeeNo     NetPay     TotalSalary
-----------  -----------  -----------
   101         36000        36000
   102         74000        110000
   103         83000        193000
   104         70000        263000
   105         18000        281000

RANK

RANK 函数根据提供的列对记录进行排序。RANK 函数还可以根据排名过滤返回的记录数。

Syntax

下面是使用 RANK 函数的通用语法。

RANK() OVER
([PARTITION BY columnnlist] [ORDER BY columnlist][DESC|ASC])

Example

考虑以下 Employee 表。

EmployeeNo

FirstName

LastName

JoinedDate

DepartmentID

BirthDate

101

Mike

James

3/27/2005

1

1/5/1980

102

Robert

Williams

4/25/2007

2

3/5/1983

103

Peter

Paul

3/21/2007

2

4/1/1983

104

Alex

Stuart

2/1/2008

2

11/6/1984

105

Robert

James

1/4/2008

3

12/1/1984

下面的查询按加入日期对员工表中的记录排序,并按加入日期分配排名。

SELECT EmployeeNo, JoinedDate,RANK()
OVER(ORDER BY JoinedDate) as Seniority
FROM Employee;

执行以上查询后,将产生以下输出。

EmployeeNo   JoinedDate   Seniority
-----------  ----------  -----------
   101       2005-03-27       1
   103       2007-03-21       2
   102       2007-04-25       3
   105       2008-01-04       4
   104       2008-02-01       5

PARTITION BY 子句按 PARTITION BY 子句中定义的列对数据进行分组,并在每个组内执行 OLAP 函数。下面是使用 PARTITION BY 子句的查询示例。

SELECT EmployeeNo, JoinedDate,RANK()
OVER(PARTITION BY DeparmentNo ORDER BY JoinedDate) as Seniority
FROM Employee;

执行上述查询时,它会产生以下输出。可以看到每个部门的排名都已重置。

EmployeeNo  DepartmentNo  JoinedDate   Seniority
-----------  ------------  ----------  -----------

    101           1        2005-03-27       1
    103           2        2007-03-21       1
    102           2        2007-04-25       2
    104           2        2008-02-01       3
    105           3        2008-01-04       1

Teradata - Data Protection

本章介绍了 Teradata 中提供的用于数据保护的功能。

Transient Journal

Teradata 使用临时日志来防止事务失败导致的数据丢失。每当运行任何事务时,临时日志都会保留受影响行的映像副本,直到事务成功或成功回滚为止。然后,将丢弃之前的映像。临时日志保存在每个 AMP 中。这是一个自动过程,并且无法禁用。

Fallback

备用保护通过在另一个称为备用 AMP 的 AMP 上存储表的第二行副本来保护表数据。如果一个 AMP 发生故障,则可以访问备用行。这样,即使一个 AMP 发生故障,数据仍然可以通过备用 AMP 获得。备用选项可以在创建表时或创建表后使用。备用可确保始终将表行的第二副本存储在另一个 AMP 中,以防止 AMP 故障导致数据丢失。但是,备用占据了插入/删除/更新操作的两倍存储空间和 I/O。

以下图表显示了如何将行的备用副本存储在另一个 AMP 中。

fallback

Down AMP Recovery Journal

当 AMP 发生故障并且表受到备用保护时,会激活 Down AMP 恢复日志。此日志会跟踪对发生故障的 AMP 的数据的所有更改。日志会在集群中剩余的 AMP 上激活。这是一个自动过程,并且无法禁用。当有故障的 AMP 恢复后,Down AMP 恢复日志中的数据将与 AMP 同步。完成此操作后,将丢弃日志。

down amp recovery journal

Cliques

隔离是一种机制,Teradata 使用它来保护数据免遭节点故障的影响。隔离只不过是一组共享一组公共磁盘阵列的 Teradata 节点。当一个节点发生故障时,有故障节点的 vproc 将迁移到隔离中的其他节点,并继续访问其磁盘阵列。

Hot Standby Node

热备用节点是不参与生产环境的节点。如果一个节点发生故障,则有故障节点的 vproc 将迁移到热备用节点。一旦恢复发生故障的节点,它将成为热备用节点。热备用节点用于在发生节点故障时维持性能。

RAID

独立磁盘冗余阵列 (RAID) 是一种用于保护数据免受磁盘故障影响的机制。磁盘阵列由一组磁盘组成,这些磁盘被分组为一个逻辑单元。此单元在用户看来可能像一个单元,但可能分布在多个磁盘上。

RAID 1 通常在 Teradata 中使用。在 RAID 1 中,每个磁盘都与一个镜像磁盘关联。对主磁盘中的数据的任何更改也会反映在镜像副本中。如果主磁盘发生故障,则可以访问镜像磁盘中的数据。

raid

Teradata - User Management

本章讨论了 Teradata 中用户管理的各种策略。

Users

使用 CREATE USER 命令创建用户。在 Teradata 中,用户类似于数据库。它们都可被分配空间并包含数据库对象,只不过用户被分配了密码。

Syntax

以下是 CREATE USER 的语法。

CREATE USER username
AS
[PERMANENT|PERM] = n BYTES
PASSWORD = password
TEMPORARY = n BYTES
SPOOL = n BYTES;

创建用户时,必须提供用户名、永久空间和密码的值。其他字段是可选的。

Example

以下是创建用户 TD01 的示例。

CREATE USER TD01
AS
PERMANENT = 1000000 BYTES
PASSWORD = ABC$124
TEMPORARY = 1000000 BYTES
SPOOL = 1000000 BYTES;

Accounts

创建新用户时,可以将用户分配给一个帐号。CREATE USER 中的 ACCOUNT 选项用于分配帐号。用户可被分配给多个帐号。

Syntax

以下是使用帐户选项的 CREATE USER 的语法。

CREATE USER username
PERM = n BYTES
PASSWORD = password
ACCOUNT = accountid

Example

以下示例创建用户 TD02,并将帐户分配为 IT 和 Admin。

CREATE USER TD02
AS
PERMANENT = 1000000 BYTES
PASSWORD = abc$123
TEMPORARY = 1000000 BYTES
SPOOL = 1000000 BYTES
ACCOUNT = (‘IT’,’Admin’);

用户可以在登录 Teradata 系统时或使用 SET SESSION 命令登录系统后指定帐户 ID。

.LOGON username, passowrd,accountid
OR
SET SESSION ACCOUNT = accountid

Grant Privileges

GRANT 命令用于将数据库对象的多个权限分配给用户或数据库。

Syntax

以下是 GRANT 命令的语法。

GRANT privileges ON objectname TO username;

权限可以是 INSERT、SELECT、UPDATE 和 REFERENCES。

Example

以下是一个 GRANT 语句的示例。

GRANT SELECT,INSERT,UPDATE ON Employee TO TD01;

Revoke Privileges

REVOKE 命令从用户或数据库中删除权限。REVOKE 命令只能删除显式权限。

Syntax

以下是 REVOKE 命令的基本语法。

REVOKE [ALL|privileges] ON objectname FROM username;

Example

以下是一个 REVOKE 命令的示例。

REVOKE INSERT,SELECT ON Employee FROM TD01;

Teradata - Performance Tuning

本章讨论 Teradata 中的性能调优过程。

Explain

性能调优的第一步是针对查询使用 EXPLAIN。EXPLAIN 计划提供优化器执行查询的详细信息。在 EXPLAIN 计划中,检查关键字(如置信级别、已使用的联接策略、假脱机文件大小、重新分配等)。

Collect Statistics

优化器使用数据人口统计数据提出有效的执行策略。COLLECT STATISTICS 命令用于收集表的数据人口统计数据。确保收集的列上的统计数据是最新的。

  1. 收集 WHERE 子句和作为联接条件使用的列上使用的列的统计数据。

  2. 收集唯一主键索引列的统计数据。

  3. 收集非唯一辅助索引列的统计数据。优化器将决定使用 NUSI 还是全表扫描。

  4. 收集联接索引的统计数据(虽然已经收集了基本表的统计数据)。

  5. 收集分区列的统计数据。

Data Types

确保使用适当的数据类型。这将避免使用超出所需的大量存储空间。

Conversion

确保联接条件所用列的数据类型兼容,以避免显式数据转换。

Sort

除非需要,否则删除不必要的 ORDER BY 子句。

Spool Space Issue

如果查询超过用户为每个 AMP 分配的卷轴空间限制,则会生成卷轴空间错误。验证执行计划并确定占用更多卷轴空间的步骤。可以将这些中间查询拆分并分别放置以构建临时表。

Primary Index

确保表的主索引正确定义。主索引列应均匀分布数据,并且应经常用于访问数据。

SET Table

如果您定义 SET 表,则优化器会检查对于所插入的每条记录,是否存在重复记录。若要删除重复检查条件,您可以为表定义唯一二级索引。

UPDATE on Large Table

更新大型表会很耗时。您可以删除记录并插入包含修改后的行的新记录,而不是更新表。

Dropping Temporary Tables

如果不再需要,请删除临时表(暂存表)和临时变量。这将释放永久空间和卷轴空间。

MULTISET Table

如果您确信输入记录没有重复记录,则可以将目标表定义为 MULTISET 表,以避免使用 SET 表执行重复行检查。

Teradata - FastLoad

FastLoad 实用工具用于将数据加载到空表中。因为它不使用瞬态日志,所以数据可以快速加载。即使目标表是 MULTISET 表,它也不会加载重复行。

Limitation

目标表不应具有辅助索引、联接索引和外键引用。

How FastLoad Works

FastLoad 分两阶段执行。

Phase 1

  1. 解析引擎从输入文件读取记录,并将一个块发送到每个 AMP。

  2. 每个 AMP 存储记录块。

  3. 然后 AMP 对每个记录进行哈希处理,并将它们重新分配到正确的 AMP。

  4. 在第 1 阶段结束时,每个 AMP 都有自己的行,但它们不在行哈希序列中。

Phase 2

  1. 当 FastLoad 接收 END LOADING 语句时,第 2 阶段开始。

  2. 每个 AMP 根据行哈希对记录进行排序,并将它们写入磁盘。

  3. 目标表上的锁被释放,错误表被删除。

Example

使用以下记录创建一个文本文件,并将该文件命名为 employee.txt。

101,Mike,James,1980-01-05,2010-03-01,1
102,Robert,Williams,1983-03-05,2010-09-01,1
103,Peter,Paul,1983-04-01,2009-02-12,2
104,Alex,Stuart,1984-11-06,2014-01-01,2
105,Robert,James,1984-12-01,2015-03-09,3

下面是一个示例 FastLoad 脚本,用于将上述文件加载到 Employee_Stg 表中。

LOGON 192.168.1.102/dbc,dbc;
   DATABASE tduser;
   BEGIN LOADING tduser.Employee_Stg
      ERRORFILES Employee_ET, Employee_UV
      CHECKPOINT 10;
      SET RECORD VARTEXT ",";
      DEFINE in_EmployeeNo (VARCHAR(10)),
         in_FirstName (VARCHAR(30)),
         in_LastName (VARCHAR(30)),
         in_BirthDate (VARCHAR(10)),
         in_JoinedDate (VARCHAR(10)),
         in_DepartmentNo (VARCHAR(02)),
         FILE = employee.txt;
      INSERT INTO Employee_Stg (
         EmployeeNo,
         FirstName,
         LastName,
         BirthDate,
         JoinedDate,
         DepartmentNo
      )
      VALUES (
         :in_EmployeeNo,
         :in_FirstName,
         :in_LastName,
         :in_BirthDate (FORMAT 'YYYY-MM-DD'),
         :in_JoinedDate (FORMAT 'YYYY-MM-DD'),
         :in_DepartmentNo
      );
   END LOADING;
LOGOFF;

Executing a FastLoad Script

在创建 input 文件 employee.txt 并且 FastLoad 脚本被命名为 EmployeeLoad.fl 后,您可以在 UNIX 和 Windows 中使用以下命令运行 FastLoad 脚本。

FastLoad < EmployeeLoad.fl;

执行上述命令后,FastLoad 脚本将运行并生成日志。在日志中,您可以看到 FastLoad 处理的记录数量和状态码。

**** 03:19:14 END LOADING COMPLETE
   Total Records Read              =  5
   Total Error Table 1             =  0  ---- Table has been dropped
   Total Error Table 2             =  0  ---- Table has been dropped
   Total Inserts Applied           =  5
   Total Duplicate Rows            =  0
   Start:   Fri Jan  8 03:19:13 2016
   End  :   Fri Jan  8 03:19:14 2016
**** 03:19:14 Application Phase statistics:
              Elapsed time: 00:00:01 (in hh:mm:ss)
0008  LOGOFF;
**** 03:19:15 Logging off all sessions

FastLoad Terms

以下是 FastLoad 脚本中常用的术语列表。

  1. LOGON − 登录到 Teradata 并发起一个或多个会话。

  2. DATABASE − 设置默认数据库。

  3. BEGIN LOADING − 标识要加载的表。

  4. ERRORFILES − 标识需要创建/更新的 2 个错误表。

  5. CHECKPOINT − 定义何时进行检查点。

  6. SET RECORD − 指定输入文件格式为格式化、二进制、文本或非格式化。

  7. DEFINE − 定义输入文件布局。

  8. FILE − 指定输入文件名和路径。

  9. INSERT − 将输入文件中的记录插入到目标表中。

  10. END LOADING − 初始化 FastLoad 的第 2 阶段。将记录分发到目标表中。

  11. LOGOFF − 结束所有会话并终止 FastLoad。

Teradata - MultiLoad

MultiLoad 能够一次加载多张表,它还可以执行不同类型的任务,比如 INSERT、DELETE、UPDATE 和 UPSERT。它一次最多可以加载 5 张表,并且在一个脚本中最多可以执行 20 个 DML 操作。MultiLoad 不需要目标表。

MultiLoad 支持两种模式 −

  1. IMPORT

  2. DELETE

MultiLoad 除目标表外,还需要一个工作表、一个日志表和两个错误表。

  1. Log Table − 用于维护加载期间进行的检查点,该检查点将用于重新启动。

  2. Error Tables − 当错误发生时,这些表会在加载期间插入。第一个错误表存储转换错误,而第二个错误表存储重复记录。

  3. Log Table − 维护 MultiLoad 每个阶段的结果,以便重新启动。

  4. Work table − MultiLoad 脚本针对每个目标表创建一个工作表。工作表用于保存 DML 任务和输入数据。

Limitation

MultiLoad 有一些限制。

  1. 目标表上不支持唯一辅助索引。

  2. Referential integrity not supported.

  3. Triggers not supported.

How MultiLoad Works

MultiLoad 导入有五个阶段 −

  1. Phase 1 − 预备阶段 – 执行基本的设置活动。

  2. Phase 2 − DML 事务阶段 – 验证 DML 语句的语法,并将它们带入 Teradata 系统。

  3. Phase 3 − 获取阶段 – 将输入数据带入工作表并锁定该表。

  4. Phase 4 − 应用阶段 – 应用所有 DML 操作。

  5. Phase 5 − 清理阶段 – 释放表锁。

MultiLoad 脚本中涉及的步骤 −

  1. Step 1 − 设置日志表。

  2. Step 2 − 登录到 Teradata。

  3. Step 3 − 指定目标表、工作表和错误表。

  4. Step 4 − 定义输入文件布局。

  5. Step 5 − 定义 DML 查询。

  6. Step 6 − 命名 IMPORT 文件。

  7. Step 7 − 指定要使用的 LAYOUT。

  8. Step 8 − 启动加载。

  9. Step 9 − 完成加载并终止会话。

Example

使用以下记录创建一个文本文件,并将该文件命名为 employee.txt。

101,Mike,James,1980-01-05,2010-03-01,1
102,Robert,Williams,1983-03-05,2010-09-01,1
103,Peter,Paul,1983-04-01,2009-02-12,2
104,Alex,Stuart,1984-11-06,2014-01-01,2
105,Robert,James,1984-12-01,2015-03-09,3

以下示例为一个 MultiLoad 脚本,该脚本读取 employee 表中的记录并将记录加载到 Employee_Stg 表中。

.LOGTABLE tduser.Employee_log;
.LOGON 192.168.1.102/dbc,dbc;
   .BEGIN MLOAD TABLES Employee_Stg;
      .LAYOUT Employee;
      .FIELD in_EmployeeNo * VARCHAR(10);
      .FIELD in_FirstName * VARCHAR(30);
      .FIELD in_LastName * VARCHAR(30);
      .FIELD in_BirthDate * VARCHAR(10);
      .FIELD in_JoinedDate * VARCHAR(10);
      .FIELD in_DepartmentNo * VARCHAR(02);

      .DML LABEL EmpLabel;
      INSERT INTO Employee_Stg (
         EmployeeNo,
         FirstName,
         LastName,
         BirthDate,
         JoinedDate,
         DepartmentNo
      )
      VALUES (
         :in_EmployeeNo,
         :in_FirstName,
         :in_Lastname,
         :in_BirthDate,
         :in_JoinedDate,
         :in_DepartmentNo
      );
      .IMPORT INFILE employee.txt
      FORMAT VARTEXT ','
      LAYOUT Employee
      APPLY EmpLabel;
   .END MLOAD;
LOGOFF;

Executing a MultiLoad Script

创建输入文件 employee.txt 并将 MultiLoad 脚本命名为 EmployeeLoad.ml 后,可使用 UNIX 和 Windows 中的以下命令运行 MultiLoad 脚本。

Multiload < EmployeeLoad.ml;

Teradata - FastExport

FastExport 实用程序用于将数据从 Teradata 表导出到平面文件中。它还可以生成报告格式的数据。可以使用 Join 从一个或多个表中提取数据。由于 FastExport 以 64K 块导出数据,因此它对于提取大量数据非常有用。

Example

考虑以下 Employee 表。

EmployeeNo

FirstName

LastName

BirthDate

101

Mike

James

1/5/1980

104

Alex

Stuart

11/6/1984

102

Robert

Williams

3/5/1983

105

Robert

James

12/1/1984

103

Peter

Paul

4/1/1983

以下是 FastExport 脚本的一个示例。它从 employee 表中导出数据,并写入到文件 employeedata.txt 中。

.LOGTABLE tduser.employee_log;
.LOGON 192.168.1.102/dbc,dbc;
   DATABASE tduser;
   .BEGIN EXPORT SESSIONS 2;
      .EXPORT OUTFILE employeedata.txt
      MODE RECORD FORMAT TEXT;
      SELECT CAST(EmployeeNo AS CHAR(10)),
         CAST(FirstName AS CHAR(15)),
         CAST(LastName AS CHAR(15)),
         CAST(BirthDate AS CHAR(10))
      FROM
      Employee;
   .END EXPORT;
.LOGOFF;

Executing a FastExport Script

一旦脚本编写完成并命名为 employee.fx,你可以使用以下命令执行脚本。

fexp < employee.fx

执行上述命令之后,将在文件 employeedata.txt 中收到以下输出。

103       Peter          Paul           1983-04-01
101       Mike           James          1980-01-05
102       Robert         Williams       1983-03-05
105       Robert         James          1984-12-01
104       Alex           Stuart         1984-11-06

FastExport Terms

以下是 FastExport 脚本中常用的术语列表。

  1. LOGTABLE − 指定用于重启目的的日志表。

  2. LOGON − 登录到 Teradata 并发起一个或多个会话。

  3. DATABASE − 设置默认数据库。

  4. BEGIN EXPORT − 指示导出的开始。

  5. EXPORT − 指定目标文件和导出格式。

  6. SELECT − 指定导出数据的选择查询。

  7. END EXPORT − 指定 FastExport 的结束。

  8. LOGOFF − 结束所有会话并终止 FastExport。

Teradata - BTEQ

BTEQ 实用工具是 Teradata 中的一个强大实用工具,可以在批处理和交互模式下使用。它可用于运行任何 DDL 语句、DML 语句、创建宏和存储过程。BTEQ 可用于从平面文件导入数据到 Teradata 表,还可用于将数据从表中提取到文件或报告。

BTEQ Terms

以下是 BTEQ 脚本中常用的术语列表。

  1. LOGON - 用于登录到 Teradata 系统。

  2. ACTIVITYCOUNT - 返回上一个查询影响的行数。

  3. ERRORCODE − 返回前一个查询的状态代码。

  4. DATABASE − 设置默认数据库。

  5. LABEL − 向一组 SQL 命令分配一个标签。

  6. RUN FILE − 执行文件中包含的查询。

  7. GOTO − 将控制权转移到标签。

  8. LOGOFF − 从数据库注销并终止所有会话。

  9. IMPORT − 指定输入文件路径。

  10. EXPORT − 指定输出文件路径并启动导出。

Example

以下是一个 BTEQ 脚本示例。

.LOGON 192.168.1.102/dbc,dbc;
   DATABASE tduser;

   CREATE TABLE employee_bkup (
      EmployeeNo INTEGER,
      FirstName CHAR(30),
      LastName CHAR(30),
      DepartmentNo SMALLINT,
      NetPay INTEGER
   )
   Unique Primary Index(EmployeeNo);

   .IF ERRORCODE <> 0 THEN .EXIT ERRORCODE;

   SELECT * FROM
   Employee
   Sample 1;
   .IF ACTIVITYCOUNT <> 0 THEN .GOTO InsertEmployee;

   DROP TABLE employee_bkup;

   .IF ERRORCODE <> 0 THEN .EXIT ERRORCODE;

   .LABEL InsertEmployee
   INSERT INTO employee_bkup
   SELECT a.EmployeeNo,
      a.FirstName,
      a.LastName,
      a.DepartmentNo,
      b.NetPay
   FROM
   Employee a INNER JOIN Salary b
   ON (a.EmployeeNo = b.EmployeeNo);

   .IF ERRORCODE <> 0 THEN .EXIT ERRORCODE;
.LOGOFF;

上面的脚本执行以下任务。

  1. Logs into Teradata System.

  2. Sets the Default Database.

  3. 创建名为 employee_bkup 的表。

  4. 从 Employee 表中选择一条记录,以检查表中是否有任何记录。

  5. 如果表为空,则删除 employee_bkup 表。

  6. 将控制权转移到标签 InsertEmployee,它将记录插入 employee_bkup 表

  7. 检查 ERRORCODE,确保在每个 SQL 语句之后该语句都成功执行。

  8. ACTIVITYCOUNT 返回上一条 SQL 查询选择的/影响的记录数。