Teradata SQL 转换指南
本文详细介绍了 Teradata 与 BigQuery 在 SQL 语法上的异同,这些信息可以帮助您规划迁移。使用批量 SQL 转换来批量迁移 SQL 脚本,或使用交互式 SQL 转换来转换临时查询。
数据类型
本部分显示 Teradata 和 BigQuery 中数据类型的等效项。
TeraData | BigQuery | 备注 |
---|---|---|
INTEGER |
INT64 |
|
SMALLINT |
INT64 |
|
BYTEINT |
INT64 |
|
BIGINT |
INT64 |
|
DECIMAL |
当标度(小数点后的位数)<= 9 时,使用 BigQuery 的 如果您需要强制执行自定义数字位数或范围边界(限制条件),请使用 BigQuery 的参数化小数数据类型。 Teradata 允许您通过将存储的值四舍五入来插入精确度更高的值;但是,它可以保持计算的高精确度。与 ANSI 标准相比,这可能会导致意外的舍入行为。 |
|
FLOAT |
FLOAT64 |
|
NUMERIC |
当标度(小数点后的位数)<= 9 时,使用 BigQuery 的 如果您需要强制执行自定义数字位数或范围边界(限制条件),请使用 BigQuery 的参数化小数数据类型。 Teradata 允许您通过将存储的值四舍五入来插入精确度更高的值;但是,它可以保持计算的高精确度。与 ANSI 标准相比,这可能会导致意外的舍入行为。 |
|
NUMBER |
当标度(小数点后的位数)<= 9 时,使用 BigQuery 的 如果您需要强制执行自定义数字位数或范围边界(限制条件),请使用 BigQuery 的参数化小数数据类型。 Teradata 允许您通过将存储的值四舍五入来插入精确度更高的值;但是,它可以保持计算的高精确度。与 ANSI 标准相比,这可能会导致意外的舍入行为。 |
|
REAL |
FLOAT64 |
|
CHAR/CHARACTER |
STRING |
如果您需要强制执行字符长度上限,请使用 BigQuery 的参数化 |
VARCHAR |
STRING |
如果您需要强制执行字符长度上限,请使用 BigQuery 的参数化 |
CLOB |
STRING |
|
JSON |
JSON |
|
BLOB |
BYTES |
|
BYTE |
BYTES |
|
VARBYTE |
BYTES |
|
DATE |
DATE |
BigQuery 不支持与 Teradata 在 SDF 中使用 DataForm 支持的类似的自定义格式。 |
TIME |
TIME |
|
TIME WITH TIME ZONE |
TIME |
Teradata 以 UTC 形式存储 TIME 数据类型,允许您使用 WITH TIME ZONE 语法传递 UTC 的偏移量。
BigQuery 中的 TIME 数据类型表示独立于任何日期或时区的时间。 |
TIMESTAMP |
TIMESTAMP |
Teradata 和 BigQuery 的 TIMESTAMP 数据类型都具有微秒精度(但 Teradata 支持闰秒,而 BigQuery 不支持)。Teradata 和 BigQuery 数据类型通常都与 UTC 时区相关联(详情)。 |
TIMESTAMP WITH TIME ZONE |
TIMESTAMP |
可在系统范围内为不同的用户和不同的列将 Teradata TIMESTAMP 设置为不同的时区(使用
WITH TIME ZONE )。如果没有明确指定时区,BigQuery TIMESTAMP 类型默认使用 UTC。请务必正确导出时区信息(请勿在未指定时区信息的情况下串联 DATE 和 TIME 值),这样 BigQuery 可以在导入时进行转换。也可以在导出前确保将时区信息转换为 UTC。BigQuery 使用 DATETIME 提取民用时间(输出时不显示时区),TIMESTAMP 则是始终显示 UTC 时区的精确时间点。 |
ARRAY |
ARRAY |
|
MULTI-DIMENSIONAL ARRAY |
ARRAY |
在 BigQuery 中使用结构体数组,每个结构体包含一个 ARRAY 类型的字段(如需了解详情,请参阅 BigQuery 文档)。 |
INTERVAL HOUR |
INT64 |
|
INTERVAL MINUTE |
INT64 |
|
INTERVAL SECOND |
INT64 |
|
INTERVAL DAY |
INT64 |
|
INTERVAL MONTH |
INT64 |
|
INTERVAL YEAR |
INT64 |
|
PERIOD(DATE) |
DATE 、DATE |
PERIOD(DATE) 应转换为包含开始日期和结束日期的两个 DATE 列,以便它们可用于窗口函数。 |
PERIOD(TIMESTAMP WITH TIME ZONE) |
TIMESTAMP 、TIMESTAMP |
|
PERIOD(TIMESTAMP) |
TIMESTAMP 、TIMESTAMP |
|
PERIOD(TIME) |
TIME 、TIME |
|
PERIOD(TIME WITH TIME ZONE) |
TIME 、TIME |
|
UDT |
STRING |
|
XML |
STRING |
|
TD_ANYTYPE |
STRING |
如需详细了解类型转换,请参阅下一部分。
Teradata 类型格式设置
Teradata SQL 使用一组默认格式来显示表达式和列数据,并用于数据类型之间的转换。例如,INTEGERDATE
模式中的 PERIOD(DATE)
数据类型默认采用 YY/MM/DD
格式。我们建议您尽可能使用 ANSIDATE 模式以确保 ANSI SQL 合规性,并借此机会清理旧格式。
Teradata 允许使用 FORMAT
子句自动应用自定义格式,而无需更改底层存储;您可以在使用 DDL 创建表时将该子句作为数据类型特性,或者在派生表达式中使用该子句。例如,FORMAT
规范 9.99
将任意 FLOAT
值四舍五入为两位数。在 BigQuery 中,必须使用 ROUND()
函数转换此功能。
此功能需要处理复杂的边缘情况。例如,将 FORMAT
子句应用于 NUMERIC
列时,您必须考虑特殊舍入和格式设置规则。FORMAT
子句可用于将 INTEGER
Epoch 值隐式转换为 DATE
格式。或者,VARCHAR
列中的 FORMAT
规范 X(6)
会截断列值,因此必须将其转换为 SUBSTR()
函数。此行为不符合 ANSI SQL 规定。因此,我们建议不要将列格式迁移到 BigQuery。
如果必须使用列格式,请使用视图或用户定义的函数 (UDF)。
如需了解 Teradata SQL 对每种数据类型使用的默认格式,请参阅 Teradata 默认格式文档。
时间戳和日期类型格式
下表汇总了 Teradata SQL 与 GoogleSQL 在时间戳和日期格式元素之间的差异。
Teradata 格式 | Teradata 说明 | BigQuery |
---|---|---|
CURRENT_TIMESTAMP
|
Teradata 中的 TIME 和 TIMESTAMP 信息可以具有不同的时区信息(使用 WITH
TIME ZONE 定义)。 |
如果可能,请使用 ISO 格式的 CURRENT_TIMESTAMP() 。但输出格式始终显示 UTC 时区。(BigQuery 在内部没有时区。)请注意以下有关 ISO 格式差异的详细信息。 DATETIME 是根据输出渠道惯例设置格式的。在 BigQuery 命令行工具和 BigQuery 控制台中,系统使用符合 RFC 3339 的 T 分隔符设置其格式。但在 Python 和 Java JDBC 中,使用空格作为分隔符。如果您想使用明确的格式,请使用明确显示字符串的 FORMAT_DATETIME() 。例如,以下表达式始终返回空格分隔符:CAST(CURRENT_DATETIME() AS STRING) Teradata 支持在 TIME 列中使用 DEFAULT 关键字来设置当前时间(时间戳);BigQuery 中不使用此关键字。 |
CURRENT_DATE |
使用以下公式将日期作为 INT64 值存储在 Teradata 中:(YEAR - 1900) * 10000 + (MONTH * 100) + DAY 日期可以采用整数格式。 |
BigQuery 采用单独的 DATE 格式,始终以 ISO 8601 格式返回日期。DATE_FROM_UNIX_DATE 不能使用,因为它是从 1970 年开始计算的。Teradata 支持在 DATE 列中使用 DEFAULT 关键字来设置当前日期;BigQuery 中不使用此关键字。 |
CURRENT_DATE-3 |
日期值以整数表示。Teradata 支持对日期类型使用算术运算符。 |
对于日期类型,使用 DATE_ADD() 或 DATE_SUB() 。BigQuery 对以下数据类型使用算术运算符: INT64 、NUMERIC 和 FLOAT64 。 |
SYS_CALENDAR.CALENDAR |
Teradata 提供的日历操作视图不仅仅是整数操作。 | 在 BigQuery 中不使用。 |
SET SESSION DATEFORM=ANSIDATE |
将会话或系统日期格式设置为 ANSI (ISO 8601)。 | BigQuery 始终使用 ISO 8601,因此请务必转换 Teradata 日期和时间。 |
查询语法
本部分介绍了 Teradata 和 BigQuery 在查询语法上的差异。
SELECT
语句
大多数 Teradata SELECT
语句都与 BigQuery 兼容。下表列出了一些细微差异。
TeraData | BigQuery | |
---|---|---|
SEL |
转换为 SELECT 。BigQuery 不使用 SEL 缩写。 |
|
SELECT
|
在 BigQuery 中,列无法引用在同一 SELECT 列表中定义的其他列的输出。首选将子查询移至 WITH 子句。
WITH flags AS (
|
|
SELECT * FROM table
|
BigQuery 不使用 ANY 逻辑谓词。可以使用多个 OR 运算符实现相同的功能:SELECT * FROM table 在这种情况下,字符串比较也会有所不同。请参阅比较运算符。 |
|
SELECT TOP 10 * FROM table
|
BigQuery 会在查询末尾使用 LIMIT ,而不是在 SELECT 关键字之后使用 TOP n 。 |
比较运算符
下表显示了 Teradata 专用的 Teradata 比较运算符,并且必须转换为 BigQuery 中使用的符合 ANSI SQL:2011 的运算符。
如需了解 BigQuery 中的运算符,请参阅 BigQuery 文档的运算符部分。
TeraData | BigQuery | 备注 |
---|---|---|
exp EQ exp2 exp IN (exp2, exp3)
|
exp = exp2 exp IN (exp2, exp3) 要保留 NOT CASESPECIFIC 的非 ANSI 语义,您可以使用 RTRIM(UPPER(exp)) = RTRIM(UPPER(exp2)) |
在比较字符串是否相等时,Teradata 可能会忽略尾随空白,而 BigQuery 会将其视为字符串的一部分。例如,'xyz'=' xyz' 在 Teradata 中为 TRUE ,但在 BigQuery 中为 FALSE 。Teradata 还提供一个
NOT CASESPECIFIC 列特性,用于指示 Teradata 在比较两个字符串时忽略大小写。在比较字符串时,BigQuery 始终区分大小写。例如,'xYz' = 'xyz' 在 Teradata 中为 TRUE ,但在 BigQuery 中为 FALSE 。 |
exp LE exp2 |
exp <= exp2 |
|
exp LT exp2 |
exp < exp2 |
|
exp NE exp2 |
exp <> exp2
|
|
exp GE exp2 |
exp >= exp2 |
|
exp GT exp2 |
exp > exp2 |
JOIN
条件
BigQuery 和 Teradata 支持相同的 JOIN
、ON
和 USING
条件。下表列出了一些细微差异。
TeraData | BigQuery | 备注 |
---|---|---|
FROM A LEFT OUTER JOIN B ON A.date >
B.start_date AND A.date < B.end_date
|
FROM A LEFT OUTER JOIN (SELECT d FROM B JOIN
UNNEST(GENERATE_DATE_ARRAY(B.start_date, B.end_date)) d)
B ON A.date = B.date
|
对于所有内部联接或者如果至少给定了一个相等性条件 (=),BigQuery 支持不等性 JOIN 子句。但 OUTER JOIN 中不只包含一个不等式条件(= 和 <)。此类构造有时会用于查询日期或整数范围。BigQuery 可防止用户无意中创建大型交叉联接。 |
FROM A, B ON A.id = B.id
|
FROM A JOIN B ON A.id = B.id
|
在 Teradata 表之间使用英文逗号相当于 INNER JOIN ,而在 BigQuery 中则相当于 CROSS JOIN (笛卡尔积)。由于 BigQuery 旧版 SQL 中的英文逗号被视为 UNION ,因此我们建议明确相应操作,避免混淆。 |
FROM A JOIN B ON
(COALESCE(A.id , 0) = COALESCE(B.id, 0))
|
FROM A JOIN B ON
(COALESCE(A.id , 0) = COALESCE(B.id, 0))
|
标量(常量)函数没有区别。 |
FROM A JOIN B ON
A.id = (SELECT MAX(B.id) FROM B)
|
FROM A JOIN (SELECT MAX(B.id) FROM B)
B1 ON A.id = B1.id
|
BigQuery 禁止用户在联接谓词中使用子查询、相关子查询或聚合。这可让 BigQuery 并行执行查询。 |
类型转换
与 Teradata 相比,BigQuery 的数据类型更少,但范围更广,这要求 BigQuery 更严格地进行类型转换。
TeraData | BigQuery | 备注 |
---|---|---|
exp EQ exp2 exp IN (exp2, exp3)
|
exp = exp2 exp IN (exp2, exp3) 要保留 NOT CASESPECIFIC 的非 ANSI 语义,您可以使用 RTRIM(UPPER(exp)) = RTRIM(UPPER(exp2)) |
在比较字符串是否相等时,Teradata 可能会忽略尾随空白,而 BigQuery 会将其视为字符串的一部分。例如,'xyz'=' xyz' 在 Teradata 中为 TRUE ,但在 BigQuery 中为 FALSE 。Teradata 还提供一个
NOT CASESPECIFIC 列特性,用于指示 Teradata 在比较两个字符串时忽略大小写。在比较字符串时,BigQuery 始终区分大小写。例如,'xYz' = 'xyz' 在 Teradata 中为 TRUE ,但在 BigQuery 中为 FALSE 。 |
CAST(long_varchar_column AS CHAR(6))
|
LPAD(long_varchar_column, 6)
|
有时,在 Teradata 中转换字符列是一种用于创建填充子字符串的非标准且非最佳方式。 |
CAST(92617 AS TIME)
92617 (FORMAT '99:99:99')
|
PARSE_TIME("%k%M%S", CAST(92617 AS STRING)) |
Teradata 比 BigQuery 执行更多隐式类型转换和舍入操作,BigQuery 通常更为严格,并强制执行 ANSI 标准。 (此示例返回 09:26:17) |
CAST(48.5 (FORMAT 'zz') AS FLOAT)
|
CAST(SUBSTR(CAST(48.5 AS STRING), 0, 2) AS FLOAT64) |
浮点和数字数据类型在应用于货币等格式时可能需要特殊的舍入规则。 (此示例返回 48) |
另请参阅比较运算符和列格式。比较和列格式设置的行为都可能类似于类型转换。
QUALIFY
、ROWS
子句
使用 Teradata 中的 QUALIFY
子句,您可以过滤窗口函数的结果。也可以使用 ROWS
短语完成相同任务。这些作业类似于 GROUP
子句的 HAVING
条件,限制 BigQuery 中调用窗口函数时的输出。
TeraData | BigQuery |
---|---|
SELECT col1, col2
|
具有窗口函数(如 ROW_NUMBER() 、SUM() 和 COUNT() )且包含 OVER PARTITION BY 的 Teradata QUALIFY 子句在 BigQuery 中表示为包含该分析值的子查询的 WHERE 子句。使用 ROW_NUMBER() :SELECT col1, col2 使用支持较大分区的 ARRAY_AGG :
SELECT
|
SELECT col1, col2
|
SELECT col1, col2 在 BigQuery 中, RANGE 和 ROWS 都可以在窗口框架子句中使用。但是,窗口子句只能用于窗口函数(如 AVG() ),不能用于编号函数(如 ROW_NUMBER() )。 |
NORMALIZE
关键字
Teradata 为 SELECT
子句提供 NORMALIZE
关键字,以将重叠的时间段或时间间隔合并为包含所有单个时间段值的单个时间段或时间间隔。
BigQuery 不支持 PERIOD
类型,因此 Teradata 中的任何 PERIOD
类型列都必须作为两个单独的 DATE
或 DATETIME
字段(分别对应时间段的开始和结束)插入 BigQuery。
TeraData | BigQuery |
---|---|
SELECT NORMALIZE
|
SELECT
|
函数
以下部分列出了 Teradata 函数与 BigQuery 等效函数之间的对应。
聚合函数
下表列出了常见的 Teradata 聚合、统计聚合和近似聚合函数与其 BigQuery 等效函数的对应。BigQuery 还提供以下聚合函数:
ANY_VALUE
APPROX_COUNT_DISTINCT
APPROX_QUANTILES
APPROX_TOP_COUNT
APPROX_TOP_SUM
COUNTIF
LOGICAL_AND
LOGICAL_OR
STRING_AGG
TeraData | BigQuery |
---|---|
AVG |
AVG |
BITAND |
BIT_AND |
BITNOT |
按位非运算符 (~ ) |
BITOR |
BIT_OR |
BITXOR |
BIT_XOR |
CORR |
CORR |
COUNT |
COUNT |
COVAR_POP |
COVAR_POP |
COVAR_SAMP |
COVAR_SAMP |
MAX |
MAX |
MIN |
MIN |
REGR_AVGX |
AVG( |
REGR_AVGY |
AVG( |
REGR_COUNT |
SUM( |
REGR_INTERCEPT |
AVG(dep_var_expression) - AVG(ind_var_expression) *
(COVAR_SAMP(ind_var_expression,
|
REGR_R2 |
(COUNT(dep_var_expression)* |
REGR_SLOPE |
- COVAR_SAMP(ind_var_expression, |
REGR_SXX |
SUM(POWER(ind_var_expression, 2)) -
COUNT(ind_var_expression) * |
REGR_SXY |
SUM(ind_var_expression * dep_var_expression) -
COUNT(ind_var_expression) |
REGR_SYY |
SUM(POWER(dep_var_expression, 2)) -
COUNT(dep_var_expression) |
SKEW |
自定义用户定义的函数。 |
STDDEV_POP |
STDDEV_POP |
STDDEV_SAMP |
STDDEV_SAMP,
STDDEV |
SUM |
SUM |
VAR_POP |
VAR_POP |
VAR_SAMP |
VAR_SAMP,
VARIANCE |
分析函数和窗口函数
下表列出了常见的 Teradata 分析和聚合分析函数与其 BigQuery 窗口函数等效函数的对应。BigQuery 还提供以下其他函数:
日期/时间函数
下表列出了常见的 Teradata 日期/时间函数与其 BigQuery 等效函数的对应。BigQuery 还提供以下日期/时间函数:
CURRENT_DATETIME
DATE_ADD
DATE_DIFF
DATE_FROM_UNIX_DATE
DATE_SUB
DATE_TRUNC
DATETIME
DATETIME_ADD
DATETIME_DIFF
DATETIME_SUB
DATETIME_TRUNC
PARSE_DATE
PARSE_DATETIME
PARSE_TIME
PARSE_TIMESTAMP
STRING
TIME
TIME_ADD
TIME_DIFF
TIME_SUB
TIME_TRUNC
TIMESTAMP
TIMESTAMP_ADD
TIMESTAMP_DIFF
TIMESTAMP_MICROS
TIMESTAMP_MILLIS
TIMESTAMP_SECONDS
TIMESTAMP_SUB
TIMESTAMP_TRUNC
UNIX_DATE
UNIX_MICROS
UNIX_MILLIS
UNIX_SECONDS
TeraData | BigQuery |
---|---|
ADD_MONTHS |
DATE_ADD,
TIMESTAMP_ADD
|
CURRENT_DATE |
CURRENT_DATE
|
CURRENT_TIME |
CURRENT_TIME
|
CURRENT_TIMESTAMP |
CURRENT_TIMESTAMP
|
DATE + k |
DATE_ADD(date_expression,
INTERVAL k DAY)
|
DATE - k |
DATE_SUB(date_expression,
INTERVAL k DAY)
|
EXTRACT |
EXTRACT(DATE),
EXTRACT(TIMESTAMP)
|
FORMAT_DATE
|
|
FORMAT_DATETIME
|
|
FORMAT_TIME
|
|
FORMAT_TIMESTAMP
|
|
LAST_DAY |
LAST_DAY 注意:此函数支持 DATE 和 DATETIME 输入表达式。 |
MONTHS_BETWEEN |
DATE_DIFF(date_expression, date_expression, MONTH)
|
NEXT_DAY |
DATE_ADD( |
OADD_MONTHS |
DATE_SUB( |
td_day_of_month |
EXTRACT(DAY FROM date_expression) |
td_day_of_week |
EXTRACT(DAYOFWEEK FROM date_expression) |
td_day_of_year |
EXTRACT(DAYOFYEAR FROM date_expression) |
td_friday |
DATE_TRUNC( |
td_monday |
DATE_TRUNC( |
td_month_begin |
DATE_TRUNC(date_expression, MONTH)
|
td_month_end |
DATE_SUB( |
td_month_of_calendar |
(EXTRACT(YEAR FROM date_expression) - 1900) * 12 + EXTRACT(MONTH FROM date_expression)
|
td_month_of_quarter |
EXTRACT(MONTH FROM date_expression) |
td_month_of_year |
EXTRACT(MONTH FROM date_expression) |
td_quarter_begin |
DATE_TRUNC(date_expression, QUARTER)
|
td_quarter_end |
DATE_SUB( |
td_quarter_of_calendar |
(EXTRACT(YEAR FROM date_expression) |
td_quarter_of_year |
EXTRACT(QUARTER FROM date_expression) |
td_saturday |
DATE_TRUNC( |
td_sunday |
DATE_TRUNC( |
td_thursday |
DATE_TRUNC( |
td_tuesday |
DATE_TRUNC( |
td_wednesday |
DATE_TRUNC( |
td_week_begin |
DATE_TRUNC(date_expression, WEEK)
|
td_week_end |
DATE_SUB( |
td_week_of_calendar |
(EXTRACT(YEAR FROM date_expression) - 1900) * 52 + EXTRACT(WEEK FROM date_expression)
|
td_week_of_month |
EXTRACT(WEEK FROM date_expression) |
td_week_of_year |
EXTRACT(WEEK FROM date_expression) |
td_weekday_of_month |
CAST( |
td_year_begin |
DATE_TRUNC(date_expression, YEAR)
|
td_year_end |
DATE_SUB( |
td_year_of_calendar |
EXTRACT(YEAR FROM date_expression)
|
TO_DATE |
PARSE_DATE
|
TO_TIMESTAMP |
PARSE_TIMESTAMP
|
TO_TIMESTAMP_TZ |
PARSE_TIMESTAMP
|
字符串函数
下表列出了 Teradata 字符串函数与其 BigQuery 等效函数的对应。BigQuery 还提供以下字符串函数:
BYTE_LENGTH
CODE_POINTS_TO_BYTES
ENDS_WITH
FROM_BASE32
FROM_BASE64
FROM_HEX
NORMALIZE
NORMALIZE_AND_CASEFOLD
REGEXP_CONTAINS
REGEXP_EXTRACT
REGEXP_EXTRACT_ALL
REPEAT
REPLACE
SAFE_CONVERT_BYTES_TO_STRING
SPLIT
STARTS_WITH
STRPOS
TO_BASE32
TO_BASE64
TO_CODE_POINTS
TO_HEX
数学函数
下表列出了 Teradata 数学函数与其 BigQuery 等效函数的对应。BigQuery 还提供以下数学函数:
TeraData | BigQuery |
---|---|
ABS |
ABS |
ACOS |
ACOS |
ACOSH |
ACOSH |
ASIN |
ASIN |
ASINH |
ASINH |
ATAN |
ATAN |
ATAN2 |
ATAN2 |
ATANH |
ATANH |
CEILING |
CEIL |
CEILING |
CEILING |
COS |
COS |
COSH |
COSH |
EXP |
EXP |
FLOOR |
FLOOR |
GREATEST |
GREATEST |
LEAST |
LEAST |
LN |
LN |
LOG |
LOG |
MOD (% 运算符) |
MOD |
NULLIFZERO |
NULLIF(expression, 0) |
POWER (** 运算符) |
POWER,
POW
|
RANDOM |
RAND |
ROUND |
ROUND |
SIGN |
SIGN |
SIN |
SIN |
SINH |
SINH |
SQRT |
SQRT |
TAN |
TAN |
TANH |
TANH |
TRUNC |
TRUNC |
ZEROIFNULL |
IFNULL(expression, 0),
COALESCE(expression, 0)
|
DML 语法
本部分介绍了 Teradata 和 BigQuery 在数据管理语言语法上的差异。
INSERT
语句
大多数 Teradata INSERT
语句都与 BigQuery 兼容。下表显示了例外情况。
BigQuery 中 DML 脚本的一致性语义与 Teradata 中的等效语句略有不同。如需简要了解快照隔离以及会话和事务处理,请参阅本文档其他位置的 CREATE INDEX
部分。
TeraData | BigQuery |
---|---|
INSERT INTO table VALUES (...);
|
INSERT INTO
table (...) VALUES (...); Teradata 为不可为 Null 的列提供 DEFAULT 关键字。注意:在 BigQuery 中,只有在目标表中所有列的值根据其顺序位置按升序排列添加时,才在 INSERT 语句中省略列名称。 |
INSERT INTO table VALUES (1,2,3);
|
INSERT INTO
table VALUES (1,2,3),
Teradata 有一个多语句请求 (MSR) 的概念,该请求一次发送多个 INSERT 语句。在 BigQuery 中,由于语句之间存在隐式事务边界,因此不推荐使用。请改用多值 INSERT 。BigQuery 允许并发 INSERT 语句,但可能会让 UPDATE 排队。为了提高性能,请考虑以下方法: |
UPDATE
语句
大多数 Teradata UPDATE
语句都与 BigQuery 兼容,但以下各项除外:
- 使用
FROM
子句时,FROM
和SET
子句在 Teradata 和 BigQuery 中的顺序相反。 - 在 GoogleSQL 中,每条
UPDATE
语句都必须包含WHERE
关键字,后跟条件。如需更新表中的所有行,请使用WHERE true
。
最佳做法是对多个 DML 变更(而不是单个 UPDATE
和 INSERT
语句)分组。BigQuery 中 DML 脚本的一致性语义与 Teradata 中的等效语句略有不同。如需简要了解快照隔离以及会话和事务处理,请参阅本文档其他位置的 CREATE INDEX
部分。
下表显示了完成相同任务的 Teradata UPDATE
语句和 BigQuery 语句。
如需详细了解 BigQuery 中的 UPDATE
,请参阅 DML 文档中的 BigQuery UPDATE
示例。
TeraData | BigQuery | |
---|---|---|
UPDATE table_A
|
UPDATE table_A
|
|
UPDATE table alias
|
UPDATE table
|
|
UPDATE table_A
|
UPDATE table_A
|
DELETE
和 TRUNCATE
语句
DELETE
和 TRUNCATE
语句都是在不影响表架构或索引的情况下从表中删除行的方法。Teradata 和 BigQuery 都未使用 TRUNCATE
。不过,您可以使用 DELETE
语句达到相同的效果。
在 BigQuery 中,DELETE
语句必须具有 WHERE
子句。
如需删除表中的所有行(截断),请使用 WHERE true
。如需加快超大型表的截断操作速度,我们建议使用 CREATE OR REPLACE TABLE ... AS SELECT
语句,并在同一表上使用 LIMIT 0
替换自身。但是,请务必在使用时手动添加分区和聚簇信息。
Teradata 稍后会清理已删除的行。这意味着 DELETE
操作的初始执行速度快于 BigQuery 中的操作,但它们稍后需要资源,尤其是会影响表的大部分内容的大规模 DELETE
操作。如需在 BigQuery 中使用类似方法,我们建议减少 DELETE
操作的数量,例如将不会删除的行复制到新表中。或者,您也可以移除整个分区。这两个选项都被设计为比原子 DML 变更更快的操作。
如需详细了解 BigQuery 中的 DELETE
,请参阅 DML 文档中的 DELETE
示例。
TeraData | BigQuery |
---|---|
BEGIN TRANSACTION;
|
使用查询输出替换表的内容相当于事务。为此目的,您可以执行查询操作或复制操作。 使用查询操作:
bq query --replace --destination_table table_A 'SELECT * FROM table_B';
使用复制操作: bq cp -f table_A table_B |
DELETE database.table ALL; |
DELETE FROM table WHERE TRUE; 或者,对于超大型表,使用更快的方法: CREATE OR REPLACE table AS SELECT * FROM table LIMIT 0; |
MERGE
语句
MERGE
语句可以将 INSERT
、UPDATE
和 DELETE
操作合并为一个“upsert”语句,并以原子方式执行这些操作。对应每个目标行,MERGE
操作必须匹配最多一个源行。BigQuery 和 Teradata 均遵循 ANSI 语法。
Teradata 的 MERGE
操作仅限于匹配访问模块处理器 (AMP) 中的主键。相比之下,BigQuery 对 MERGE
操作没有大小或列限制,因此使用 MERGE
是一种有用的优化措施。但是,如果 MERGE
主要是大量删除,请参阅本文档中 DELETE
的优化。
BigQuery 中 DML 脚本的一致性语义与 Teradata 中的等效语句略有不同。例如,在 MERGE
操作期间,Teradata 的 SET 表在会话模式中可能会忽略重复项。如需简要了解如何处理 MULTISET 和 SET 表、快照隔离以及会话和事务处理,请参阅本文档其他位置的 CREATE INDEX
部分。
行影响的变量
在 Teradata 中,ACTIVITY_COUNT
变量是一个 Teradata ANSI SQL 扩展程序,其中填充了受 DML 语句影响的行数。
脚本功能中的 @@row_count
系统变量具有类似功能。在 BigQuery 中,更常见的做法是在审核日志或 INFORMATION_SCHEMA
视图中检查 numDmlAffectedRows
返回值。
DDL 语法
本部分介绍了 Teradata 和 BigQuery 在数据定义语言语法上的差异。
CREATE TABLE
语句
大多数 Teradata CREATE TABLE
语句都与 BigQuery 兼容,但以下语法元素在 BigQuery 中不使用:
MULTISET
。请参阅CREATE INDEX
部分。VOLATILE
。请参阅临时表部分。[NO] FALLBACK
。请参阅回滚部分。[NO] BEFORE JOURNAL
、[NO] AFTER JOURNAL
CHECKSUM = DEFAULT | val
DEFAULT MERGEBLOCKRATIO
PRIMARY INDEX (col, ...)
。请参阅CREATE INDEX
部分。UNIQUE PRIMARY INDEX
。请参阅CREATE INDEX
部分。CONSTRAINT
DEFAULT
IDENTITY
如需详细了解 BigQuery 中的 CREATE TABLE
,请参阅 DML 文档中的 BigQuery CREATE
示例。
列选项和特性
BigQuery 中不使用 CREATE TABLE
语句的以下列规范:
FORMAT 'format'
。请参阅 Teradata 类型格式设置部分。CHARACTER SET name
。BigQuery 始终使用 UTF-8 编码。[NOT] CASESPECIFIC
COMPRESS val | (val, ...)
Teradata 使用列 TITLE
选项扩展了 ANSI 标准。您可以使用下表中的列说明,在 BigQuery 中实现类似功能。请注意,此选项不适用于“视图”。
TeraData | BigQuery |
---|---|
CREATE TABLE table (
|
CREATE TABLE dataset.table (
|
临时表
Teradata 支持易失表,该表通常用于在脚本中存储中间结果。以下几种方法可以实现类似于 BigQuery 中易失表的功能:
CREATE TEMPORARY TABLE
可用于脚本,并且在脚本的生命周期内有效。如果表必须存在于脚本之外,您可以使用此列表中的其他选项。数据集 TTL:创建一个存留时间较短的数据集(例如,1 小时),这样在该数据集中创建的所有表都是暂时的,因为它们的持续时间不会长于数据集的存留时间。您可以为此数据集的所有表名称添加
temp
前缀,以明确表示这些表是临时表。表 TTL:使用类似于以下内容的 DDL 语句,创建具有表特定的较短存留时间的表:
CREATE TABLE temp.name (col1, col2, ...) OPTIONS(expiration_timestamp=TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR));
WITH
子句:如果仅在同一个区块内需要临时表,请使用WITH
语句或子查询的临时结果。这是最高效的选项。
Teradata 脚本 (BTEQ) 中经常使用的模式是创建永久表,在其中插入值,再在持续语句中将此作为临时表,然后删除或截断表。实际上,这会将表用作常量变量(信号量)。这种方法在 BigQuery 中效率不高,我们建议在脚本中改用实际变量,或者将 CREATE OR REPLACE
与 AS SELECT
查询语法搭配使用来创建已包含值的表。
CREATE VIEW
语句
下表显示了 Teradata 和 BigQuery 中 CREATE VIEW
语句的等效项。BigQuery 中不需要表锁定的子句(例如 LOCKING ROW FOR ACCESS
)。
TeraData | BigQuery | 备注 |
---|---|---|
CREATE VIEW view_name AS SELECT ...
|
CREATE VIEW
view_name AS SELECT ...
|
|
REPLACE VIEW view_name AS SELECT ...
|
CREATE OR REPLACE VIEW
|
|
不支持 |
CREATE VIEW IF NOT EXISTS
|
仅当指定的数据集中不存在要创建的视图时才创建此视图。 |
CREATE [UNIQUE] INDEX
语句
Teradata 要求所有表都有索引,并需要特殊解决方法(如 MULTISET 表和 NoPI 表)来处理非唯一或未编入索引的数据。
BigQuery 不需要索引。本节介绍 BigQuery 中用于创建功能的方法,这些功能类似于在实际需要业务逻辑的 Teradata 中使用索引的方式。
为确保性能而进行索引
由于它是一个面向列的数据库,具有查询和存储优化功能,因此 BigQuery 不需要显式索引。BigQuery 提供分区和聚簇以及嵌套字段等功能,可通过优化数据存储方式来提高查询效率和性能。
Teradata 不支持具体化视图。但是,它提供使用 CREATE JOIN INDEX
语句的联接索引,该语句实质上会物化联接所需的数据。BigQuery 不需要具体化索引来提高性能,正如它不需要联接的专用假脱机空间一样。
对于其他优化情况,您可以使用物化视图。
为确保一致性而进行索引(UNIQUE、PRIMARY INDEX)
在 Teradata 中,可以使用唯一索引来防止表中包含存在非唯一键的行。如果进程尝试插入或更新具有已编入索引的值的数据,则该操作会因索引违规失败(MULTISET 表),或以静默方式忽略该操作(SET 表)。
由于 BigQuery 不提供显式索引,因此可以使用 MERGE
语句仅将暂存表中的唯一记录插入目标表,同时舍弃重复记录。但是,由于 BigQuery 在 INSERT
操作期间从不锁定,因此无法阻止具有修改权限的用户插入重复记录。要在 BigQuery 中生成重复记录错误,您可以使用暂存表中的 MERGE
语句,如以下示例所示。
TeraData | BigQuery | |
---|---|---|
CREATE [UNIQUE] INDEX name;
|
MERGE `prototype.FIN_MERGE` t
|
通常情况下,用户更愿意单独删除重复项,以发现下游系统中的错误。
BigQuery 不支持 DEFAULT
和 IDENTITY
(序列)列。
进行索引以实现锁定
Teradata 提供访问模块处理器 (AMP) 中的资源;查询可以使用全 AMP、单 AMP 或群组 AMP 资源。DDL 语句是全 AMP 语句,因此类似于全局 DDL 锁定。BigQuery 没有这样的锁定机制,可以运行并发查询和 INSERT
语句直至配额上限;仅并发 UPDATE
DML 语句具有某些并发影响:同一分区的 UPDATE
操作会排队以确保快照隔离,因此您不必通过锁定来防止幻读或丢失更新。
由于存在这些差异,因此在 BigQuery 中不使用以下 Teradata 元素:
ON COMMIT DELETE ROWS;
ON COMMIT PRESERVE ROWS;
过程 SQL 语句
本部分介绍如何将存储过程、函数和触发器中使用的过程 SQL 语句从 Teradata 转换为 BigQuery 脚本、过程或用户定义的函数 (UDF)。所有这些可供系统管理员使用 INFORMATION_SCHEMA
视图进行检查。
CREATE PROCEDURE
语句
存储过程作为 BigQuery 脚本的一部分受支持。
在 BigQuery 中,脚本指的是使用控制语句的任何代码,而过程是命名的脚本(如果需要则带有参数),可以根据需要从其他脚本调用并永久存储。用户定义的函数 (UDF) 也可用 JavaScript 编写。
TeraData | BigQuery |
---|---|
CREATE PROCEDURE |
CREATE PROCEDURE (如果需要名称),否则请使用 BEGIN 内嵌或使用带有 CREATE TEMP FUNCTION 的单行。 |
REPLACE PROCEDURE |
CREATE OR REPLACE PROCEDURE |
CALL |
CALL |
以下部分介绍了将现有 Teradata 过程语句转换为具有类似功能的 BigQuery 脚本语句的方法。
变量声明和赋值
BigQuery 变量在脚本的生命周期内有效。
TeraData | BigQuery |
---|---|
DECLARE |
DECLARE |
SET |
SET |
错误情况处理程序
Teradata 在过程中的状态代码上使用处理程序进行错误控制。在 BigQuery 中,错误处理是主控制流的核心功能,类似于其他语言通过 TRY ... CATCH
块提供的功能。
TeraData | BigQuery |
---|---|
DECLARE EXIT HANDLER
FOR SQLEXCEPTION |
BEGIN ... EXCEPTION WHEN ERROR THEN |
SIGNAL sqlstate |
RAISE message |
DECLARE CONTINUE HANDLER
FOR SQLSTATE VALUE 23505; |
BigQuery 不使用针对特定错误情况触发的异常处理程序。 我们建议使用 ASSERT 语句(其中退出条件用于预检查或调试),因为这符合 ANSI SQL:2011 标准。 |
Teradata 中的 SQLSTATE
变量类似于 BigQuery 中的 @@error
系统变量。在 BigQuery 中,更常见的是使用审核日志记录或 INFORMATION_SCHEMA
视图调查错误。
游标声明和操作
由于 BigQuery 不支持游标或会话,因此 BigQuery 中不会使用以下语句:
DECLARE cursor_name CURSOR [FOR | WITH] ...
PREPARE stmt_id FROM sql_str;
OPEN cursor_name [USING var, ...];
FETCH cursor_name INTO var, ...;
CLOSE cursor_name;
动态 SQL 语句
BigQuery 中的脚本功能支持下表所示的动态 SQL 语句。
TeraData | BigQuery |
---|---|
EXECUTE IMMEDIATE
sql_str; |
EXECUTE IMMEDIATE
sql_str; |
EXECUTE
stmt_id [USING var,...]; |
EXECUTE IMMEDIATE
stmt_id USING var; |
以下动态 SQL 语句在 BigQuery 中不使用:
PREPARE stmt_id FROM sql_str;
控制流语句
BigQuery 中的脚本功能支持下表所示的控制流语句。
TeraData | BigQuery |
---|---|
IF condition THEN stmts ELSE stmts END IF
|
IF condition THEN stmts ELSE stmts END IF |
label_name: LOOP stmts END LOOP label_name;
|
BigQuery 不使用 GOTO 样式的块构造。 我们建议将它们重写为用户定义的函数 (UDF) 或者在使用它们来进行错误处理的地方使用 ASSERT 语句。 |
REPEAT stmts UNTIL condition END REPEAT;
|
WHILE condition DO stmts END WHILE |
LEAVE outer_proc_label;
|
LEAVE 不用于 GOTO 样式的块;它被用作 BREAK 离开 WHILE 循环的同义词。 |
LEAVE label;
|
LEAVE 不用于 GOTO 样式的块;它被用作 BREAK 离开 WHILE 循环的同义词。 |
WITH RECURSIVE temp_table AS ( ... );
|
BigQuery 中不使用递归查询(也称为递归通用表表达式 (CTE))。您可以使用 UNION ALL 数组重写递归查询。 |
BigQuery 中不使用以下控制流语句,因为 BigQuery 不使用游标或会话:
元数据和事务 SQL 语句
TeraData | BigQuery |
---|---|
HELP TABLE table_name;
HELP VIEW view_name;
|
SELECT 同一查询对于获取视图的列信息有效。 如需了解详情,请参阅 BigQuery INFORMATION_SCHEMA 中的列视图。 |
SELECT * FROM dbc.tables WHERE tablekind = 'T'; (Teradata DBC 视图) |
SELECT 如需了解详情,请参阅 BigQuery INFORMATION_SCHEMA 简介。 |
HELP STATISTICS table_name; |
APPROX_COUNT_DISTINCT(col) |
COLLECT STATS USING SAMPLE ON table_name column (...); |
在 BigQuery 中不使用。 |
LOCKING TABLE table_name FOR EXCLUSIVE; |
BigQuery 始终使用快照隔离。如需了解详情,请参阅本文档其他位置的一致性保证。 |
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ... |
BigQuery 始终使用快照隔离。如需了解详情,请参阅本文档其他位置的一致性保证。 |
BEGIN TRANSACTION; |
BigQuery 始终使用快照隔离。如需了解详情,请参阅本文档其他位置的一致性保证。 |
EXPLAIN ... |
在 BigQuery 中不使用。 类似的功能是 BigQuery 网页界面中的查询计划说明以及 INFORMATION_SCHEMA 视图和 Cloud Monitoring 的审核日志记录功能中可见的槽分配。 |
多语句和多行 SQL 语句
Teradata 和 BigQuery 都支持事务(会话),因此支持用分号分隔并始终一起执行的语句。如需了解详情,请参阅多语句事务。
错误代码和消息
Teradata 错误代码与 BigQuery 错误代码有所不同。提供 REST API 时,BigQuery 主要依赖于 HTTP 状态代码以及详细的错误消息。
如果您的应用逻辑当前捕获以下错误,请尝试消除错误源,因为 BigQuery 不返回相同的错误代码。
SQLSTATE = '02000'
-“未找到行”SQLSTATE = '21000'
—“基数违规(唯一索引)”SQLSTATE = '22000'
—“数据违规(数据类型)”SQLSTATE = '23000'
—“限制条件违规”
在 BigQuery 中,更常见的是使用 INFORMATION_SCHEMA
视图或审核日志记录功能来深入分析错误。
如需了解如何在脚本中处理错误,请参阅以下部分。
一致性保证和事务隔离
Teradata 和 BigQuery 都是原子性的,也就是说,在多行的每个变更级别都符合 ACID。例如,即使插入和更新了多个值,MERGE
操作也是完全原子化的。
交易
当在会话模式(而不是自动提交模式)下运行时,Teradata 提供读取未提交(允许脏读取)或可序列化事务隔离级别。理想情况下,Teradata 通过对所有分区的所有行列中的行哈希使用悲观锁定实现严格可序列化的隔离。可能会出现死锁的情况。DDL 始终强制执行事务边界。Teradata Fastload 任务独立运行,但仅在空表上运行。
BigQuery 也支持事务。BigQuery 使用快照隔离帮助确保乐观并发控制(首先提交胜出),其中查询在查询开始之前读取最后提交的数据。此方法可保证每行的每个变更和同一 DML 语句中的各行具有相同的一致性级别,同时避免死锁。如果针对同一个表有多个 UPDATE
语句,BigQuery 会切换到悲观并发控制,并将多个 UPDATE
语句排入队列,在发生冲突时自动重试。INSERT
DML 语句和加载作业可以并发和独立运行,以附加到表中。
回滚
Teradata 支持两种会话回滚模式,即 ANSI 会话模式和 Teradata 会话模式(SET SESSION CHARACTERISTICS
和 SET SESSION TRANSACTION
),具体取决于您所需的回滚模式。如果失败,事务可能不会回滚。
BigQuery 支持 ROLLBACK TRANSACTION
语句。BigQuery 中没有 ABORT
语句。
数据库限制
请务必查看 BigQuery 公开文档,了解最新的配额和限制。大批量用户的许多配额可通过联系 Cloud 支持团队提高。下表显示了 Teradata 和 BigQuery 数据库限制的比较。
限制 | TeraData | BigQuery |
---|---|---|
每个数据库的表数 | 无限制 | 无限制 |
每个表的列数 | 2048 | 10000 |
行大小上限 | 1 MB | 100 MB |
列名称和表名称的长度 | 128 个 Unicode 字符 | 16384 个 Unicode 字符 |
每个表的行数 | 无限制 | 无限制 |
SQL 请求长度上限 | 1 MB | 1 MB(未解析 GoogleSQL 查询长度上限) 12 MB(已解析旧版 SQL 查询长度上限和 GoogleSQL 查询长度上限) 流式传输:
|
请求和响应的大小上限 | 7 MB(请求),16 MB(响应) | 10 MB(请求)和 10 GB(响应),如果您使用分页或 Cloud Storage API,则几乎没有限制。 |
并发会话数量上限 | 每个解析引擎 (PE) 120 个 | 100 个并发查询(可通过槽预留提高),每位用户 300 次并发 API 请求。 |
并发(快速)加载数量上限 | 30(默认为 5) | 无并发限制;将任务加入队列。每个项目每天 100000 项加载作业。 |