摘要:去O一直是金融保险行业永恒的话题,但去O的难度之大也只有真正经历过的人才知其中的艰辛。此次笔者结合实际去O工作,对去O过程中碰到的DBLINK、SEQ
UENCE最大值、空串、SQL语句中的别名等等近50个问题进行探讨,绝对是干货满满,诚意十足!
PostgreSQL VS Oracle
站在开发和应用的角度看,底层数据库搭建再好,但如果应用在上面跑不起来,跑的不好,新数据库平台就会变成一座鬼城。 今天,我分享的内容分四大部分,一是技术选型。第二、三是今天的重点,怎么让应用真正在新的数据库平台上面跑起来,这是要探究的一个问题。会涉及到一些比较细节的东西,尤其对于开发人员可能会更加关注一些,当然对于DBA来说,也是需要去注意的。 金融行业技术选型有个特点,当你向公司推荐一个数据库产品时,领导肯定会问个问题,同行业有没有在使用的? 我为什么会选择PostgreSQL?一个很重要的原因是不少同行在用,比如,平安科技。那抛开同行业,PostgreSQL自身有哪些优势?

我们做了PostgreSQL与Oracle的对比,就单体模式来说, PostgreSQL完全不输给Oracle,可以做到完全实时的同步,单体保持数据同步方面一点问题都没有。

分片模式, Oracle提供了一个Sharding模式。相对应的PostgreSQL有XC/XL解决方案。当然咯,这个方案也不是完美的,比如说GTM可能会成为性能的瓶颈点,很有可能会成为一个瓶颈。

2
让应用先跑起来
能不能让应用正确的跑起来,这是事关生存的问题。事关你新系统能不能在公司里面生存下来的问题,这个是非常关键的问题。 下面,涉及到很多往PostgreSQL迁应用时遇到的问题,总结如下: 1、 字符集问题: PostgreSQL服务端是不支持GBK的,我们用UTF8。PostgreSQL还有个编码EUC CN,这个我们之前测过很多次,有很多生僻字是无法编码的。 比如“瑄”在EUC_CN下就无法编码。因此,不推荐使用EUC_CN。 2、多行注释问题: /* some comments/* other comments/*******************/• 上述注释在Oracle中是合法的• 在POSTGRESQL中是非法的• -- 合法的PostgreSQL注释格式:• -- This is a standard SQL comment• /* multiline comment• * with nesting: /* nested comment */• */• 可以使用PLY(Python-Lex-Yacc)将注释自动改写掉 3、NUMERIC类型问题:



在PostgreSQL中,CHAR类型的长度是实际有效字符的长度,这个和Oracle很不一样。这个在应用中如果不注意的话,就会报很多错误。而且,有时候查起来非常困难。当然我们也可以通过重载函数的方式来模拟Oracle中的行为。 6、SEQUENCE最大值问题
•POSTGRESQL的SEQUENCE最大值:9223372036854775807(bigint)•而Oracle中的SEQUENCE最大值可达28位十进制值•一般情况下POSTGRESQL的SEQUENCE是足够的•但可能也存在一些特殊情况:{LISCODE.SEQ_YBTBATTRANS_ID '10000000000000072561' }{ 该值明显已超出最大值} { 使用NUMERIC类型,配合触发器使用}
通常情况下PostgreSQL中SEQUENCE足够使用。但上面这个值已经超出最大值,目前,我的解决办法是把它用NUMERIC类型配合触发器使用,用触发器模拟序列类型,如果你是频繁插入,性能下降会非常严重,这是需要注意的问题。
7、类型转换 # CREATE TABLE t1 (id VARCHAR(32));# SELECT * FROM t1 WHERE id = 27;ERROR: operator does not exist: character varying = integerLINE 1: SELECT * FROM t1 WHERE id = 27; ^HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.CREATE CAST (varchar AS integer)WITH INOUTAS IMPLICIT;# SELECT * FROM t1 WHERE id = 27; id----(0 rows)# EXPLAIN verbose SELECT * FROM t1 WHERE id = 27; QUERY PLAN ----------------------------------------------------------- Seq Scan on public.t1 (cost=0.00..22.95 rows=4 width=82) Output: id Filter: ((t1.id)::integer = 27)(3 rows)• 善用CAST• 根据自己的需求,绘制类型转换矩阵 如果对Oracle熟悉,就会知道Oracle是由明确的类型转换矩阵的,在PostgreSQL里,这方面就差一点。但PostgreSQL提供了自定义创建CAST的特性。在我们实际迁移过程当中,如果你能够把CAST利用好是能解决很大一部分问题的。 7、操作符重载

比如说SELECT 3/5是个雷,除了它本身3对应的是INT4,5对应的也是INT4,所以它本身是一个非整型数字,但是,它也是会被截断掉。进行一个重载就可以解决,我们重新定义一个函数,可以用系统的numeric div,这样用户不需要做任何的修改就可以达到跟Oracle一样的效果。
总结一下,操作符重载是PostgreSQL提供的一个非常好的特性,善用操作符重载可以解决一些兼容性问题,以及前面说的CAST是可以解决很多监管系统问题的,在这个过程中也是有很多问题需要注意的。 第一、POSTGRESQL本身它设置了很多类型转换和操作符,这个一定要考虑是否有冲突。第二、类型转化的操作也需要相互配合,因为在调用操作符时,是要判断类型转换是否需要自己去做的,所以,这两个是需要密切配合才能完美的使用好。 8、子查询 Oracle当中子查询不需要别名alias,但在PostgreSQL当中是不行的。

9、SELECT表达式别名问题 下种这种语句在Oracle里面没有任何问题,但在PostgreSQL就会出问题。

究其原因,是PostgreSQL认为name是关键字,不能使用。但是这也有矛盾的地方。比如uncommited这个关键字和name是一样的级别,但是uncommited就可以用来做别名。这个问题还需要研究。 9、SELECT INTO
这个问题也是需要特别注意,如果本身的代码没有这方面的错误处理,很有可能就会导致结果错误。

10、UPDATE语句问题
UPDATE语句中不能使用下面这个在Oracle可能很常见的写法。INSERT也一样。这个也不能说谁对谁错,因为本身SQL标准中就不支持这样的写法的,PostgreSQL只是遵从了这个标准而已。



这就需要增加一个重试机制。 不过我们觉得Oracle_fdw事务级别设置的过于严格了,所以我们对源码做了简单的修改,把事务级别降下来.
修改后,实际使用中运行良好。 13、空串('')、NULL问题 空串和NULL也是非常头疼的问题,因为在Oracle当中空串和NULL是等价的,我个人更加偏向于PostgreSQL设计,更严谨。PostgreSQL里面空串是空串,NULL是NULL,但从Oracle牵引过来会碰到很多的问题。

从应用代码当中执行,代码当中包括绑定变量的方式,比如我们先选一下当前有没有NULL值,当前是零,这里是空串,再去执行同样的语句,会发现已经正确插进去了。这个是我们对PostgreSQL本身开源技术上做的一些小优化。 14、SYNONYM问题 PostgreSQL中是没有SYNONYM这个概念的1、可以通过调整search_path来解决2、配合使用VIEW 15、列名大小写问题 Oracle中的列名是大写表示的PostgreSQL中的列名是小写表示的在使用类似MyBatis这样的工具时,需要将大写转为小写,否则会导致你的列名找不到的问题,这个是需要特别注意的一个地方。 16、如何支持PACKAGE? PostgreSQL中没有PACKAGE这个概念我们使用了schema来模拟。这是Oracle官方网站里的一个案例,大家可以自己看一下。
17、其他 其他的还有,decode函数,Wm conca为函数,dual,utl_file,dbms_pipe,dbms_output,package, 我们非常推荐使用orafce开源组件,功能挺强大的。 以上是在实际迁移系统过程中,可能会遇到的各种“坑”点,趟过所有这些“坑”,应用才可以完成生存的第一步:活着!
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!