logo
GBase 8a
适配迁移
文章

南大通用数据迁移之GaussDB_To_GBase8a(三)迁移SQL差异

Robin
发表于2024-06-19 18:09:03701次浏览0个评论

1.大小写敏感差异

GaussDB中SQL语法关于双引号的规则:不带双引号的标识强制转换成小写,而双引号保护字母不进行大小写转换,并且允许在标识符中使用空白。在双引号中,成对的双引号在结果名字中分析成一个双引号。比如,FOO"BAR"BAZ解析成fooBARbaz;而"Aweird""name"解析成A weird"name。
GBase 8a在默认情况下是大小写敏感的。

2.业务隔离对象差异

GaussDB 200中可以使用Database和Schema实现业务的隔离,区别在于Database的隔离更加彻底,各个Database之间共享资源极少,可实现连接隔离、权限隔离等,Database之间无法直接互访。Schema隔离的方式共用资源较多,可以通过grant与revoke语法便捷地控制不同用户对各Schema及其下属对象的权限。 跨Schema访问语法:Schema.table
GBase 8a使用Database实现业务隔离,支持Database之间互相访问,跨库访问语法:数据库名.表名。

3.编码差异

        数据库编码查看
        GaussDB建议创建Database的时候使用UTF-8编码,可以通过查看字符集编码(ENCODING)和兼容性 (DBCOMPATIBILITY)两个配置项来确定。GaussDB 200支持Teradata和Oracle两种兼容模式,不同兼容模式下的语法行为可能有一些差异。
        GaussDB 200支持GBK、UTF-8和Latin1编码格式,设置字符集有两种方式:
        1)在安装数据库时指定初始化参数-E; 
        2)通过SQL语句创建数据库时指定ENCODING参数,如:CREATE DATABASE mydb WITH ENCODING 'GBK' 
        GaussDB数据库的默认存储编码集(server_encoding)可以通过“show server_encoding”命令查看。GaussDB不指定编码时,默认使用模版数据库的编码。模板数据库template0和template1的编码默认与操作系统环境相关。template1不允许修改字符编码,如果要变更编码,需要使用template0创建数据库。 
        GBase 8a默认是UTF8编码,不支持创建库的时候指定编码。可以执行下面的sql查看:

Show variables like ‘%character%’;

迁移时先检查确认GaussDB数据库编码和GBase 8a的编码。从GaussDB中导出数据时请指定GBase 8a的数据库编码。
        迁移数据时导出文件编码的指定
GaussDB导出数据一般使用外表导出,支持导出过程中转换编码。如果GaussDB与GBase 8a字符集不一致,在创建外表时请指定ENCODING为GBase 8a的编码。GBase 8a的加载不支持转换编码,所以加载的数据文件需要预先统一编码跟GBase 8a一致才能正确加载。
 

CREATE FOREIGN TABLE product_info_ext
(
... 
) 
SERVER gsmpp_server 
OPTIONS(
LOCATION 'gsfs://192.168.0.90:5000/*',
FORMAT 'CSV' ,
DELIMITER ',',
ENCODING 'utf8',
HEADER 'false',
FILL_MISSING_FIELDS 'true',
IGNORE_EXTRA_DATA 'true'
)
READ ONLY
LOG INTO product_info_err 
PER NODE REJECT LIMIT 'unlimited';

encoding 参数说明:
指定数据文件的编码格式名称,即需要以何编码格式对数据文件进行解析和 校验/输出文件为何种编码格式。缺省值为当前数据库的默认客户端编码格式,即client_encoding。 

4.开发注意事项

        GBase 8a不支持级联,迁移时sql带级联相关的部分删除。
        GBase 8a 不支持事务,迁移时事务的语句需要删除,包括JDBC等接口应用也需要检查是否有打开事务的sql,如果有需要删除。
        在JDBC向GaussDB 200申请连接的代码中,需要显式打开autocommit开关。 GBase 8a默认是autocommit模式,不能设置为非autocommit。
        GBase 8a 不支持WITH TABLE AS
        GaussDB中超过3张表或视图进行关联(特别是full join)时,建议使用WITH TABLE AS语句创建中间临时表的方式增加SQL语句的可读性。 迁移时需要删除,可以在GBase 8a中单独建立临时表替换。
        GaussDB中在where子句里,过滤条件有序可以提升性能,把选择读较小(筛选出的记录数较少)的条件排在前面。 GBase 8a中不需要,sql执行时会自动优化。
        在GBase 8a和GaussDB中OR的场景都很难优化,都是建议如果在过滤条件只有OR表达式的情况下,可以将OR表达式转化为UNION ALL以提升性能。如: 

SELECT * FROM scdc.pub_menu 
WHERE (cdp= 300 AND inline=301) OR (cdp= 301 AND inline=302) OR (cdp= 302 ANDinline=301); 

转换为: 


SELECT * FROM scdc.pub_menu 
WHERE (cdp= 300 AND inline=301) 
union all 
SELECT * FROM scdc.pub_menu 
WHERE (cdp= 301 AND inline=302) 
union all 
SELECT * FROM tablename 
WHERE (cdp= 302 AND inline=301)

        应用连接注意事项
应用如果迁移到GBase 8a后有格式显示发生变化,可以查看GaussDB中下面的设置项,根据这些设置项调整GBase 8a的应用接口。
        第三方工具通过JDBC连接GaussDB 200时,JDBC向GaussDB 200发起连接请求,会默认添加以下配置参数: 

params = { 
{ "user", user }, 
{ "database", database }, 
{ "client_encoding", "UTF8" }, 
{ "DateStyle", "ISO" }, 
{ "extra_float_digits", "2" }, 
{ "TimeZone", createPostgresTimeZone() }, 
}; 


        这些参数可能会导致JDBC客户端的行为与gsql客户端的行为不一致,例如,Date 数据显示方式、浮点数精度表示、timezone显示。 如果实际期望和这些配置不符,建议在java连接设置代码中显式设定这些参数。 

5.索引差异

        GBase 8a有智能索引,该索引自动在所有列上建立,不用人工维护。除了智能索引外支持人工建立和维护的只有hash索引。
        GaussDB中一般都人工创建了Partial Cluster Key(局部聚簇,简称PCK),PCK是列存表的一种局部聚簇技术,在原理上类似GBase 8a的智能索引,但是一张表上只能建立一个PCK,一个PCK可以包含多列,GaussDB一般不建议超过2列。
        GaussDB支持的索引类型较多,迁移时为了性能,索引建议全部删除。迁移至GBase 8a中后再根据需要创建hash索引。

6.NULL的应用差异

        GaussDB和GBase 8a的NULL值的比较都是只能使用IS NULL或者IS NOT NULL的方式判断,其他任何形式的逻辑判断都返回NULL。例如:NULL<>NULL、NULL=NULL和NULL<>1返回结果都是NULL,而不是期望的布尔值。 
相同的行为:
1)需要统计表中所有记录数时,不要使用count(col)来替代count(*)。count(*)会统计NULL值(真实行数),而count(col)不会统计。 
2)执行sum(col)时,当所有记录都为NULL时,最终将返回NULL;当不全为NULL时,“值为NULL”的记录行将被计数为0。
3)count(distinct col)用来计算该列不重复的非NULL的数量,NULL将不被计数。 
4)排序默认都是按照ASC & NULL LAST进行排序。使用ORDER BY子句进行排序时,可以显式指定排序方式(ASC/DESC),NULL的排序方式(NULL FIRST/NULL LAST)。 
不同的行为:
1)GaussDB中count(多个字段)时,多个字段名必须用圆括号括起来。例如,count( (col1,col2,col3) )。注意:通过多字段统计行数时,即使所选字段都为NULL,该行也被计数,效果与count(*)一致。同时也支持count(distinct (col1,col2,...))用来统计多列的唯一值数量。
      GBase 8a 不支持count(多个字段)和count(distinct (col1,col2,...))语法。
注:GaussDB 200支持Teradata和Oracle两种兼容模式,分别兼容Teradata语法和Oracle语法,不同兼容模式下的语法行为可能有一些差异,在ORACLE兼容模式下,在导入数据时,空字符串会自动转化为NULL。如果需要保留空字符串需要新建兼容性为TD的数据库。

评论

登录后才可以发表评论