IBM Netezza SQL 转换指南
IBM Netezza 数据仓储旨在与 Netezza 专属 SQL 语法协同工作。Netezza SQL 基于 Postgres 7.2。由于各种 SQL 方言有所不同,因此,如果不进行修改,则为 Netezza 编写的 SQL 脚本无法在 BigQuery 数据仓库中使用。
本文档详细介绍了 Netezza 与 BigQuery 在 SQL 语法的以下方面的异同:
- 数据类型
- SQL 语言元素
- 查询语法
- 数据操纵语言 (DML)
- 数据定义语言 (DDL)
- 存储过程
- 函数
您还可以使用批量 SQL 转换来批量迁移 SQL 脚本,或使用交互式 SQL 转换来转换临时查询。两个预览版的工具都支持 IBM Netezza SQL/NZPLSQL。
数据类型
Netezza | BigQuery | 备注 |
---|---|---|
INTEGER/INT/INT4 |
INT64 |
|
SMALLINT/INT2 |
INT64 |
|
BYTEINT/INT1 |
INT64 |
|
BIGINT/INT8 |
INT64 |
|
DECIMAL
|
NUMERIC
|
Netezza 中的 DECIMAL 数据类型是 NUMERIC 数据类型的别名。 |
NUMERIC
|
NUMERIC
INT64 |
|
NUMERIC(p,s)
|
NUMERIC
|
与 Netezza 不同,BigQuery 中的 NUMERIC 类型不强制执行自定义数字位数或范围边界(限制条件)。BigQuery 的小数点后固定了 9 位数字,而 Netezza 则允许自定义设置。在 Netezza 中,精度 p 可为 1 到 38,范围 s 可为 0 到精度。 |
FLOAT(p) |
FLOAT64 |
|
REAL/FLOAT(6) |
FLOAT64 |
|
DOUBLE PRECISION/FLOAT(14) |
FLOAT64 |
|
CHAR/CHARACTER
|
STRING
|
BigQuery 中的 STRING 类型是可变长度的,不需要手动设置最大字符长度,而 Netezza CHARACTER 和 VARCHAR 类型需要。CHAR(n) 中的 n 的默认值为 1。字符串大小上限为 64,000。 |
VARCHAR
|
STRING
|
BigQuery 中的 STRING 类型是可变长度的,不需要手动设置最大字符长度,而 Netezza CHARACTER 和 VARCHAR 类型需要。字符串大小上限为 64,000。 |
NCHAR
|
STRING
|
BigQuery 中的 STRING 类型存储为 UTF-8 编码的可变长度 Unicode。最大长度为 16,000 个字符。 |
NVARCHAR
|
STRING
|
BigQuery 中的 STRING 类型存储为 UTF-8 编码的可变长度 Unicode。最大长度为 16,000 个字符。 |
VARBINARY |
BYTES |
|
ST_GEOMETRY |
GEOGRAPHY |
|
BOOLEAN/BOOL
|
BOOL
|
BigQuery 中的 BOOL 类型只能接受 TRUE/FALSE ,而 Netezza 中的 BOOL 类型可以接受各种值,例如 0/1 、yes/no 、true/false, 、on/off 。 |
DATE |
DATE |
|
TIME |
TIME |
|
TIMETZ/TIME WITH TIME ZONE
|
TIME
|
Netezza 以 UTC 形式存储 TIME 数据类型,允许您使用 WITH TIME
ZONE 语法传递 UTC 的偏移量。BigQuery 中的 TIME 数据类型表示独立于任何日期或时区的时间。 |
TIMESTAMP
|
DATETIME
|
Netezza TIMESTAMP 类型不包含时区,与 BigQuery DATETIME 类型相同。 |
ARRAY
|
Netezza 中没有数组数据类型。数组类型存储在 varchar 字段中。 |
时间戳和日期类型格式
如需详细了解 Netezza SQL 使用的日期类型格式,请参阅 Netezza 日期时间模板模式文档。如需详细了解日期时间函数,请参阅 Netezza 日期/时间函数文档。
在将日期类型格式元素从 Netezza 转换为 GoogleSQL 时,您必须特别注意 TIMESTAMP
和 DATETIME
之间的时区差异,如下表所述:
Netezza | BigQuery |
---|---|
CURRENT_TIMESTAMP CURRENT_TIME TIME Netezza 中的信息可以具有不同的时区信息(使用 WITH TIME ZONE 语法定义)。 |
如果可能,请使用格式正确的 CURRENT_TIMESTAMP 函数。但是,输出格式并不总是显示世界协调时间 (UTC) 时区(在内部,BigQuery 没有时区)。bp 命令行工具和 Google Cloud 控制台中的 DATETIME 对象根据 RFC 3339 使用 T 作为分隔符。但在 Python 和 Java JDBC 中,使用空格作为分隔符。使用显式的 FORMAT_DATETIME 函数正确定义日期格式。否则,系统会显式转换为字符串,例如:CAST(CURRENT_DATETIME() AS STRING) 这也会返回空格分隔符。 |
CURRENT_DATE |
CURRENT_DATE |
CURRENT_DATE-3
|
BigQuery 不支持算术数据运算。请改用 DATE_ADD 函数。 |
SELECT
语句
通常情况下,Netezza SELECT
语句与 BigQuery 兼容。下表列出了例外情况:
Netezza | BigQuery |
---|---|
没有 FROM 子句的 SELECT 语句 |
支持特殊情况,例如:
|
SELECT (subquery) AS flag, CASE WHEN flag = 1 THEN ... |
在 BigQuery 中,列无法引用在同一查询中定义的其他列的输出。您必须复制逻辑或将逻辑移至嵌套查询中。 选项 1 SELECT (subquery) AS flag, CASE WHEN (subquery) = 1 THEN ... 选项 2 SELECT q.*, CASE WHEN flag = 1 THEN ... FROM ( SELECT (subquery) AS flag, ... ) AS q |
比较运算符
Netezza | BigQuery | 说明 |
---|---|---|
exp = exp2 |
exp = exp2 |
等于 |
exp <= exp2 |
exp <= exp2 |
小于或等于 |
exp < exp2 |
exp < exp2 |
小于 |
exp <> exp2 exp != exp2 |
exp <> exp2 exp != exp2 |
不等于 |
exp >= exp2
|
exp >= exp2
|
大于或等于 |
exp > exp2 |
exp > exp2 |
大于 |
内置 SQL 函数
Netezza | BigQuery | 说明 |
---|---|---|
CURRENT_DATE
|
CURRENT_DATE
|
获取当前日期(年、月、日)。 |
CURRENT_TIME
|
CURRENT_TIME
|
获取含小数的当前时间。 |
CURRENT_TIMESTAMP
|
CURRENT_TIMESTAMP
|
获取当前系统日期和时间,精确到秒。 |
NOW
|
CURRENT_TIMESTAMP
|
获取当前系统日期和时间,精确到秒。 |
COALESCE(exp, 0)
|
COALESCE(exp, 0)
|
将 NULL 替换为零。 |
NVL(exp, 0)
|
IFNULL(exp, 0)
|
将 NULL 替换为零。 |
EXTRACT(DOY FROM
timestamp_expression)
|
EXTRACT(DAYOFYEAR FROM
timestamp_expression)
|
返回从年初开始的天数。 |
ADD_MONTHS(date_expr,
num_expr) |
DATE_ADD(date,
INTERVAL k MONTH) |
向日期添加月份。 |
DURATION_ADD(date,
k) |
DATE_ADD(date,
INTERVAL k DAY) |
对日期执行加法。 |
DURATION_SUBTRACT(date,
k) |
DATE_SUB(date,
INTERVAL k DAY) |
对日期执行减法。 |
str1 || str2 |
CONCAT(str1,
str2) |
串联字符串。 |
函数
本部分比较 Netezza 和 BigQuery 函数。
聚合函数
分析函数
日期和时间函数
字符串函数
数学函数
Netezza | BigQuery |
---|---|
ABS |
ABS |
ACOS |
ACOS |
ACOSH |
|
ASIN |
ASIN |
ASINH |
|
ATAN |
ATAN |
ATAN2 |
ATAN2 |
ATANH |
|
CEIL DCEIL |
CEIL
|
CEILING |
|
COS |
COS |
COSH |
|
COT |
COT |
DEGREES |
|
DIV |
|
EXP |
EXP |
FLOOR DFLOOR |
FLOOR
|
GREATEST |
GREATEST |
IEEE_DIVIDE |
|
IS_INF |
|
IS_NAN |
|
LEAST |
LEAST |
LN |
LN |
LOG |
LOG |
LOG10 |
|
MOD |
MOD |
NULLIF (expr, 0) |
|
PI |
ACOS (-1) |
POW FPOW |
POWER POW |
RADIANS |
|
RANDOM |
RAND |
ROUND |
ROUND |
SAFE_DIVIDE |
|
SETSEED |
|
SIGN |
SIGN |
SIN |
SIN |
SINH |
|
SQRT NUMERIC_SQRT |
SQRT
|
TAN |
TAN |
TANH |
|
TRUNC |
TRUNC |
IFNULL (expr, 0) |
DML 语法
本部分比较 Netezza 和 BigQuery DML 语法。
INSERT
语句
Netezza | BigQuery |
---|---|
INSERT INTO table VALUES (...); |
INSERT INTO table (...) VALUES (...); Netezza 为列提供了 DEFAULT 关键字和其他限制条件。在 BigQuery 中,只有在指定了所有列的情况下,省略 INSERT 语句中的列名称才有效。 |
INSERT INTO table (...) VALUES (...); INSERT INTO table (...) VALUES (...); |
INSERT INTO table VALUES (), (); BigQuery 设有 DML 配额,用于限制您每天可以执行的 DML 语句数量。要充分利用您的配额,请考虑采用以下方法:
|
BigQuery 中 DML 脚本的一致性语义与 Netezza 中的等效语句略有不同。另请注意,除了 NOT
NULL
之外,BigQuery 不提供限制条件。
如需简要了解快照隔离以及会话和事务处理,请参阅一致性保证和事务隔离。
UPDATE
语句
在 Netezza 中,WHERE
子句是可选的,但在 BigQuery 中是必需的。
Netezza | BigQuery |
---|---|
UPDATE tbl SET tbl.col1=val1; |
在没有 WHERE 子句的情况下不受支持。使用 WHERE true 子句更新所有行。 |
UPDATE A SET y = B.y, z = B.z + 1 FROM B WHERE A.x = B.x AND A.y IS NULL; |
UPDATE A SET y = B.y, z = B.z + 1 FROM B WHERE A.x = B.x AND A.y IS NULL; |
UPDATE A alias SET x = x + 1 WHERE f(x) IN (0, 1) |
UPDATE A SET x = x + 1 WHERE f(x) IN (0, 1); |
UPDATE A SET z = B.z FROM B WHERE A.x = B.x AND A.y = B.y |
UPDATE A SET z = B.z FROM B WHERE A.x = B.x AND A.y = B.y; |
如需查看示例,请参阅 UPDATE
示例。
鉴于 DML 配额,我们建议您使用较大的 MERGE
语句,而不是多个单独的 UPDATE
和 INSERT
语句。BigQuery 中 DML 脚本的一致性语义与 Netezza 中的等效语句略有不同。如需简要了解快照隔离以及会话和事务处理,请参阅一致性保证和事务隔离。
DELETE
和 TRUNCATE
语句
DELETE
和 TRUNCATE
语句都是在不影响表架构或索引的情况下从表中移除行的方法。TRUNCATE
语句与 DELETE
语句具有相同的效果,但对于大型表,比 DELETE
语句快得多。Netezza 支持 TRUNCATE
语句,但 BigQuery 不支持。但是,您可以在 Netezza 和 BigQuery 中使用 DELETE
语句。
在 BigQuery 中,DELETE
语句必须具有 WHERE
子句。
在 Netezza 中,WHERE
子句是可选的。如果未指定 WHERE
子句,则 Netezza 表中的所有行都会被删除。
Netezza | BigQuery | 说明 |
---|---|---|
BEGIN; LOCK TABLE A IN EXCLUSIVE MODE; DELETE FROM A; INSERT INTO A SELECT * FROM B; COMMIT; |
使用查询输出替换表的内容相当于事务。您可以使用 query 或复制 (cp ) 操作执行此操作。bq query \ bq cp \ |
将表的内容替换为查询结果。 |
DELETE FROM database.table |
DELETE FROM table WHERE TRUE; |
在 Netezza 中,运行 delete 语句时,行并不会被物理删除,而只是标记为删除。之后运行 GROOM TABLE 或 nzreclaim 命令会移除标记为删除的行并收回相应的磁盘空间。 |
GROOM
TABLE |
Netezza 使用 GROOM TABLE 命令移除标记为删除的行,从而收回磁盘空间。 |
MERGE
语句
对应每个目标行,MERGE
语句最多只能匹配一个源行。BigQuery 中 DML 脚本的一致性语义与 Netezza 中的等效语句略有不同。如需简要了解快照隔离以及会话和事务处理,请参阅一致性保证和事务隔离。如需查看示例,请参阅 BigQuery MERGE
示例和 Netezza MERGE
示例。
DDL 语法
本部分比较 Netezza 和 BigQuery DDL 语法。
CREATE TABLE
语句
Netezza | BigQuery | 说明 |
---|---|---|
TEMP TEMPORARY
|
BigQuery 的 DDL 支持使您可以根据查询结果创建表,并在创建时指定其有效期。例如,三天:CREATE TABLE
'fh-bigquery.public_dump.vtemp' OPTIONS (expiration_timestamp=TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 3 DAY)) |
创建会话的临时表。 |
ZONE MAPS
|
不支持。 | 快速搜索 WHERE 条件。 |
DISTRIBUTE ON
|
PARTITION BY
|
分区。
这不是直接转换。DISTRIBUTE ON 在节点之间共享数据(通常使用唯一键进行均匀分布),而 PARTITION BY 会将数据精简为多个片段。 |
ORGANIZE ON
|
CLUSTER BY
|
Netezza 和 BigQuery 都最多支持四个键的聚簇。Netezza 聚簇基表 (CBT) 为每个聚簇列提供相同的优先级。在 BigQuery 中,表在其上进行聚簇的第一列优先,然后是第二列,以此类推。 |
ROW SECURITY |
Authorized View |
行级安全性。 |
CONSTRAINT |
不支持 | 检查限制条件。 |
DROP
语句
Netezza | BigQuery | 说明 |
---|---|---|
DROP TABLE |
DROP TABLE |
|
DROP DATABASE |
DROP DATABASE |
|
DROP VIEW |
DROP VIEW |
列选项和特性
Netezza | BigQuery | 说明 |
---|---|---|
NULL NOT NULL
|
NULLABLE REQUIRED
|
指定是否允许列包含 NULL 值。 |
REFERENCES
|
不支持 | 指定列限制条件。 |
UNIQUE
|
不支持 | 列中的每个值必须是唯一的。 |
DEFAULT
|
不支持 | 列中的所有值为默认值。 |
临时表
Netezza 支持在会话期间存在的 TEMPORARY
表。
如需在 BigQuery 中构建临时表,请执行以下操作:
- 创建一个存留时间较短的数据集(例如 12 小时)。
在数据集中创建临时表,表名称前缀为
temp
。例如,如需创建在一小时后到期的表,请执行以下命令:CREATE TABLE temp.name (col1, col2, ...) OPTIONS(expiration_timestamp = TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR));
开始读取和写入临时表。
您还可以单独移除重复项,以发现下游系统中的错误。
请注意,BigQuery 不支持 DEFAULT
和 IDENTITY
(序列)列。
过程 SQL 语句
Netezza 使用 NZPLSQL 脚本语言来处理存储过程。NZPLSQL 基于 Postgres 的 PL/pgSQL 语言。本部分介绍如何将存储过程、函数和触发器中使用的过程 SQL 语句从 Netezza 转换为 BigQuery。
CREATE PROCEDURE
语句
Netezza 和 BigQuery 都支持使用 CREATE PROCEDURE
语句创建存储过程。如需了解详情,请参阅使用 SQL 存储过程。
变量声明和赋值
Netezza | BigQuery | 说明 |
---|---|---|
DECLARE var
datatype(len) [DEFAULT
value]; |
DECLARE
|
声明变量。 |
SET var = value; |
SET |
为变量分配值。 |
异常处理程序
Netezza 支持可针对某些错误条件触发的异常处理程序。BigQuery 不支持条件处理程序。
Netezza | BigQuery | 说明 |
---|---|---|
EXCEPTION
|
不支持 | 声明用于一般错误的 SQL 异常处理程序。 |
动态 SQL 语句
Netezza 支持在存储过程中使用动态 SQL 查询。BigQuery 不支持动态 SQL 语句。
Netezza | BigQuery | 说明 |
---|---|---|
EXECUTE IMMEDIATE sql_str; |
EXECUTE IMMEDIATE sql_str; |
执行动态 SQL。 |
控制流语句
Netezza | BigQuery | 说明 |
---|---|---|
IF THEN ELSE STATEMENT IF conditionTHEN ... ELSE ... END IF; |
IF conditionTHEN ... ELSE ... END IF;
|
有条件地执行。 |
迭代控制FOR var AS SELECT ... DO stmts END FOR; FOR var AS cur CURSOR FOR SELECT ... DO stmts END FOR; |
不支持 | 在一系列行上迭代。 |
迭代控制LOOP stmts END LOOP; |
LOOP sql_statement_list END LOOP; |
循环执行语句块。 |
EXIT WHEN |
BREAK |
退出过程。 |
WHILE *condition* LOOP
|
WHILE conditionDO ... END WHILE |
执行语句循环,直至某个条件失败。 |
其他语句和过程语言元素
Netezza | BigQuery | 说明 |
---|---|---|
CALL proc(param,...) |
不支持 | 执行过程。 |
EXEC proc(param,...) |
不支持 | 执行过程。 |
EXECUTE proc(param,...) |
不支持 | 执行过程。 |
多语句和多行 SQL 语句
Netezza 和 BigQuery 都支持事务(会话),因此支持用分号分隔并始终一起执行的语句。如需了解详情,请参阅多语句事务。
其他 SQL 语句
Netezza | BigQuery | 说明 |
---|---|---|
GENERATE
STATISTICS
|
为当前数据库中的所有表生成统计信息。 | |
GENERATE
STATISTICS ON
table_name |
为特定表生成统计信息。 | |
GENERATE
STATISTICS ON
table_name(col1,col4)
|
使用统计函数(如 MIN, MAX, AVG, 等)、使用界面或使用 Cloud Data Loss Prevention API。 |
为表中的特定列生成统计信息。 |
GENERATE
STATISTICS ON
table_name |
APPROX_COUNT_DISTINCT(col) |
显示列的唯一值的数量。 |
INSERT INTO
table_name |
INSERT INTO
table_name |
插入一行。 |
LOCK TABLE
table_name FOR
EXCLUSIVE; |
不支持 | 锁定行。 |
SET SESSION
CHARACTERISTICS AS
TRANSACTION ISOLATION
LEVEL ...
|
BigQuery 始终使用快照隔离。如需了解详情,请参阅一致性保证和事务隔离。 | 定义事务隔离级别。 |
BEGIN TRANSACTION END TRANSACTION COMMIT |
BigQuery 始终使用快照隔离。如需了解详情,请参阅一致性保证和事务隔离。 | 定义多语句请求的事务边界。 |
EXPLAIN ...
|
不支持。查询计划和时间轴中提供类似功能 | 显示 SELECT 语句的查询计划。 |
用户视图
元数据 系统视图元数据 |
SELECT * EXCEPT(is_typed) FROM mydataset.INFORMATION_SCHEMA.TABLES; BigQuery 信息架构 |
查询数据库中的对象 |
一致性保证和事务隔离
Netezza 和 BigQuery 都是原子性的,也就是说,跨多行的每个变更都符合 ACID。例如,即使插入了多个值,MERGE
操作也是完全原子化的。
事务
Netezza 在语法上接受 ANSI SQL 事务隔离的所有四种模式。但是,无论指定哪种模式,系统只会使用 SERIALIZABLE
模式,它可提供尽可能高的一致性级别。此模式还可避免并发事务之间的脏读、不可重复读和幻读。Netezza 不使用传统锁定来实现一致性。当两个事务尝试修改相同数据时,它使用序列化依赖检查(一种乐观并发控制)来自动回滚最新事务。
BigQuery 也支持事务。BigQuery 使用快照隔离帮助确保乐观并发控制(首先提交优先),其中查询在查询开始之前读取最后提交的数据。此方法可保证每行的每个变更和同一 DML 语句中的各行具有相同的一致性级别,同时避免死锁。如果对同一个表进行了多个 DML 更新,BigQuery 会切换为悲观并发控制。加载作业可以完全独立运行并附加到表。
回滚
Netezza 支持 ROLLBACK
语句以中止当前事务并回滚在该事务中进行的所有更改。
在 BigQuery 中,您可以使用 ROLLBACK TRANSACTION
语句。
数据库限制
限额 | Netezza | BigQuery |
---|---|---|
每个数据库的表数 | 32,000 | 无限制 |
每个表的列数 | 1600 | 10000 |
行大小上限 | 64 KB | 100 MB |
列名称和表名称的长度 | 128 字节 | 16,384 个 Unicode 字符 |
每个表的行数 | 无限制 | 无限制 |
SQL 请求长度上限 | 1 MB(未解析标准 SQL 查询长度上限)。 12 MB(已解析旧版和标准 SQL 查询长度上限)。 流式插入: 10 MB(HTTP 请求大小限制) 10,000(每个请求的行数上限) |
|
请求和响应大小上限 | 10 MB(请求)和 10 GB(响应),如果您使用分页或 Cloud Storage API,则几乎没有限制。 | |
并发会话数量上限 | 63 个并发读写事务。2000 个与服务器的并发连接。 | 100 个并发查询(可通过槽预留提高),每位用户 300 次并发 API 请求。 |
后续步骤
- 查看从 IBM Netezza 迁移到 BigQuery 的分步说明。