是否可以使用Tibero代替Oracle。 并且有必要吗

在本文中,我将告诉您如何认真考虑Oracle的替代方案。 但是您说Postgre呢? 是的,但是有细微差别。 首先,我们要解决“为什么使用Oracle?”这个问题。
数据库中的业务逻辑。 在甲骨文的专业书籍中,汤姆·基特写道
在开发数据库应用程序时,我使用非常简单的口头禅:

如果可能,用一条SQL语句完成;
如果无法使用单个SQL语句完成此操作,请在PL / SQL中执行;
如果无法在PL / SQL中完成此操作,请尝试使用Java存储过程;
如果无法使用Java完成此操作,请作为C中的外部过程进行;
如果无法在C中将其实现为外部过程,则需要认真考虑为什么要这样做……
在系统设计中,我遵循此规则。 Oracle中的对象类型特别令人愉悦;在它们的帮助下,根据所有OOP规范,可以轻松漂亮地实现复杂的业务逻辑。

Oracle很昂贵。 购买它而不使用其中的所有东西将是一个错误。
但是,团队和能力始终是一个因素。 如果您的团队已经在Oracle进行了10年的开发工作,那么发布Postgre可能会很痛苦。

Oracle很昂贵。 如此昂贵,您可以多次编写它,而不必考虑在新项目中对Oracle的需求将是一个错误。

我已经好几次碰到有关韩国Tibero产品的出版物,据说是为了取代Oracle而创建的。 现在,它们具有空前慷慨的吸引力-几乎免费为开发人员分发标准许可证,而为套接字收取1美元。 因此,我们了解:韩国人目前能提供什么。 毕竟,有了汽车,他们已经(几乎)成功了!

实验说明


TMaxSoft的代表说,Tibero与Oracle几乎100%兼容,并且有一个用于数据库迁移的实用程序。 我决定将我的产品基础和Oracle中的业务逻辑一起使用PL \ SQL中OOP的所有魅力,并将其转移到Tibero。 在本出版物中,我们不考虑数据本身的迁移,它不那么有趣,并且我还没有尝试完全迁移。

任务是这样的:

1.转移表。
2.索引,键等的传送
3.传输数据包和触发器。
4.传送对象类型。

但是首先,让我们处理这些工具。

工具


Google对Tibero知之甚少。 我们以虚拟机的形式下载了数据库本身,上面已经部署了所有内容。 只有两种工具:用于迁移T-UP的实用程序,以及用于DBA和tbAdmin开发人员的IDE。 理论上,所有操作都可以用Java完成,可以在任何地方运行。

T-UP看起来像这样:


主窗口:数据库连接。


如果单击选项,则可以进行配置。


最重要的是,您可以选择要迁移的对象的类型。

找不到说明,帮助和提示。
它给人以自制工具的印象。 有时她会执行处决,但基本上她会根据需要工作。

第二个工具是Tibero Admin IDE。 如果您先在TMaxSoft网站上注册,可以从TMaxSoft网站下载。 您也可以在那里获得演示许可证。


Tibero Admin看起来像一个典型的旧IDE

我习惯了Allround Automations出色的PL / SQL Developer工具。 在Tibero Admin中,无需担心上下文提示,单击“点”后,屏幕上将不会显示任何内容,它不会将表和对象的名称附加到您的身上。 程序员,只需键入代码即可。 帮助,文档? 不行 制造商网站上的DBMS上有文档,这很有趣……无需搜索。 找不到关于IDE的文档。 但是,没有什么复杂的。 授权存在问题-事实证明,需要授予用户DBA权限才能进入tbAdmin。 对于端口而言有趣的是,8630适用于SYS,适用于所有其他8629

IDE错误。 有时,当您在某处戳戳时,消息索引会飞出,像java.lang.Exception:承诺这样的消息非常可怕。 有必要考虑不同类型的SQL和PSM窗口:第一种,您不太可能编译程序代码;第二种,您不会执行请求。 在PL / SQL Developer之后-左手的悲惨外表...

开始实验。

表迁移


我们在T-UP中选择方案,单击“迁移”,首先在选项中选择“表”,然后开始传输过程。 我遇到两个问题。

餐桌。 我决定将它们转移到表中,但是Tibero似乎已经尝试为它们保留源数据库中所占据的空间。 这很多,而他不能。 我手动创建了表空间,然后一切正常。

除了默认日期日期类型为'31 .12.2019'的表。 在Oracle设置中,我们注册了此格式,对于Tibero而言,它可以帮助
alter session set nls_date_format='DD.MM.YYYY'; 
但是T-UP无处可做。 来自TMaxSoft的同事建议设置变量TB_NLS_DATE_FORMAT =“ DD.MM.YYYY”,但它对我个人没有帮助。 也许我做错了。 我不得不手动创建带有此类参数的表,但它们并不多。

第一步的结果:将表结构从Oracle迁移到Tibero效果很好。

键和索引。


我们选中INDEX,CONSTRAINT和T-UP复选框,由于日期相同,CHECK出现了问题。 通常,已经创建了索引,主键,检查。 但是我在新创建的数据库中找不到外键。 常量的迁移在T-UP日志中以消息“迁移失败:java.lang.NullPointerException”结束。 巧合吗? 我不这么认为...

包和触发器。


在触发器中,我没有什么复杂的东西,它们是完美创建的。 是的,我没有检查它们的工作方式,这将是一个单独的故事。

让我们谈谈实现部分逻辑的过程和函数。 不幸的是,在这里并不是一切都完美。

简单:在Tibero 军队中没有单词NEW 。 o:= NEW构造t_my_type()将不会编译。 在Oracle中,这是真的,不是强制性的,但是我总是出于某种原因而写。 我必须删除。

DBA角色允许SQL Window访问所有表。 但是,当在具有这种角色的架构中编译程序包或过程时,在使用其他架构的表和对象时,需要为该对象提供相应的授权。 DBA角色的魔力在这里无济于事。

从具体。 我的数据库中出现一个奇怪的FORALL,但是可以正常工作。

 --     PROCEDURE save_tar_test AS TYPE number_table IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; TYPE date_table IS TABLE OF DATE INDEX BY BINARY_INTEGER; TYPE varchar50_table IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER; TYPE char1_table IS TABLE OF CHAR(1) INDEX BY BINARY_INTEGER; TYPE t_tar_det_out_upd_rec_test IS RECORD ( --   cmr_tar_det_id number_table, in_stamp date_table, err_code_id number_table ); tdou_rec t_tar_det_out_upd_rec_test; BEGIN --   ,  tdou_rec  :      Oracle FORALL j IN 1 .. tdou_rec.cmr_tar_det_id.COUNT UPDATE cmr_tar_det dd SET err_code_id = tdou_rec.err_code_id(j) WHERE dd.cmr_tar_det_id = tdou_rec.cmr_tar_det_id(j) AND in_stamp = tdou_rec.in_stamp(j); END; 

Tibero说: “ dml语句必须具有批量输入参数ia forall close” 。 而且我很了解它,但是必须定期重做此代码。

包含对象的表的情况更糟。

 CREATE OR REPLACE TYPE S1.TYPE_PAY_HIST AS OBJECT ( pay_status_id NUMBER(1), stamp DATE ); CREATE OR REPLACE TYPE S1.TABLE_PAY_HIST AS VARRAY(10) OF type_pay_hist; create table S2.RECEIPT ( receipt_id NUMBER(8) not null, pay_sum NUMBER(12,2) not null, receipt_hist S1.TABLE_PAY_HIST ); FUNCTION receipt_status_change(p_cmr_receipt_id NUMBER, p_new_status NUMBER) RETURN NUMBER AS l_receipt_hist s1.table_pay_hist; l_type_pay_hist s1.type_pay_hist; l_status NUMBER; BEGIN BEGIN SELECT receipt_hist INTO l_receipt_hist FROM receipt p WHERE p.receipt_id = p_cmr_receipt_id FOR UPDATE; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN c_err_not_find_status; END; ... END; 

我们遇到编译错误,键入mistmatch。

来自TMaxSoft的人员提出了此版本的代码:

 create or replace FUNCTION .... AS l_receipt_hist table_pay_hist; l_type_pay_hist type_pay_hist; l_status NUMBER; cmr_receipt_row cmr_receipt%rowtype; BEGIN BEGIN SELECT * INTO cmr_receipt_row FROM cmr_receipt p WHERE p.cmr_receipt_id = p_cmr_receipt_id FOR UPDATE; SELECT TYPE_PAY_HIST(r.pay_status_id,r.stamp) bulk collect INTO l_receipt_hist FROM cmr_receipt p,table(p.receipt_hist) r WHERE p.cmr_receipt_id = p_cmr_receipt_id; EXCEPTION WHEN NO_DATA_FOUND THEN dbms_output.put_line('NO_DATA_FOUND'); RETURN null;--c_err_not_find_status; END; ... END; 

工作可能有效。 但不是很方便,您必须重做代码。

除SDO_GEOM之类的特定内容外,其余部分均正常编译。 顺便提一下,Tibero有一个类似物。 他的手尚未到达书房。

种类


在其中一个项目中,我们使用Oracle空洞的OOP的功能。
对于Tibero来说,最令人兴奋的问题就是这个。

我们创建一个特定类型,这对于其他类型集合是基本的。

 CREATE OR REPLACE TYPE t_tar_object AS OBJECT ( id NUMBER(12), smth NUMBER(12), CONSTRUCTOR FUNCTION t_tar_object RETURN SELF AS RESULT, MEMBER FUNCTION target(param IN NUMBER DEFAULT NULL) RETURN NUMBER, MEMBER FUNCTION inside(o t_tar_object) RETURN NUMBER, MEMBER FUNCTION clone RETURN t_tar_object ) NOT FINAL; --  CREATE OR REPLACE TYPE BODY t_tar_object AS CONSTRUCTOR FUNCTION t_tar_object RETURN SELF AS RESULT AS BEGIN RETURN; END; MEMBER FUNCTION target(param IN NUMBER DEFAULT NULL) RETURN NUMBER AS BEGIN RETURN id; END; MEMBER FUNCTION clone RETURN t_tar_object AS BEGIN RETURN NULL ; END; END; 

现在,我们正在努力为他创造一个值得继承的继承人。

 CREATE OR REPLACE TYPE t_tar_service UNDER t_tar_object ( is_virtual NUMBER(1), CONSTRUCTOR FUNCTION t_tar_service (p_serv_obj t_tar_object, p_main_id NUMBER, p_pack_id NUMBER) RETURN SELF AS RESULT, OVERRIDING MEMBER FUNCTION target(param IN NUMBER DEFAULT NULL) RETURN NUMBER, OVERRIDING MEMBER FUNCTION clone RETURN t_tar_object ) NOT FINAL; 

编译器将拒绝覆盖目标函数。 但是,没有关于克隆功能的问题。 事实证明,当该方法具有参数时,Tibero不喜欢覆盖。 好的,删除“覆盖”一词。 但这令人震惊,我们编写了测试脚本。 到目前为止与父类型有关。

 declare o1 t_tar_object; i1 number := 100; begin o1 := t_tar_object; o1.id := 1; i1 := o1.target; -- dbms_output.put_line (i1)   . --      ,  ,     i1   -- if i1 > 0 then dbms_output.put_line ('big'); end if; if i1 < 0 then dbms_output.put_line ('small'); end if; if i1 = 0 then dbms_output.put_line ('zero'); end if; if i1 is null then dbms_output.put_line ('null'); end if; end; 

似乎我们没有给程序留下选择的余地,无论变量i1取什么值,输出中都会出现一些东西。 但是……什么也没出现!


我立刻想起了一部很棒的电影

这种怪异并不止于此。 使实验更糟

 declare o1 t_tar_object; i1 number := 100; begin o1 := t_tar_object; o1.id := 1; i1 := o1.target; --  ,      -    i1 := 2; if i1 > 0 then dbms_output.put_line ('big'); end if; if i1 < 0 then dbms_output.put_line ('small'); end if; if i1 = 0 then dbms_output.put_line ('zero'); end if; if i1 is null then dbms_output.put_line ('null'); end if; end; 

甚至在使用对象的方法进行所有操作之后,我们严格设置变量的值这一事实也不会改变任何内容-输出为空。

控制实验,测试自己的精神错乱:

 declare o1 t_tar_object; i1 number ; begin o1 := t_tar_object; o1.id := 1; --i1 := o1.target;    i1 := 2; if i1 > 0 then dbms_output.put_line ('big'); end if; if i1 < 0 then dbms_output.put_line ('small'); end if; if i1 = 0 then dbms_output.put_line ('zero'); end if; if i1 is null then dbms_output.put_line ('null'); end if; end; 

珍惜的“大”出现在输出中。 令人毛骨悚然,不是吗? 来自TMaxSoft的家伙用科学的戳法发现,如果您从t_tar_object规范中删除了“ NOT FINAL”细微差别,则该对象将表现适当。 但是,为什么我们需要没有继承人的……。

在Tibero中进一步谈论OOP是没有意义的。 实际上,就像提比洛的OOP。 之后,又出现了另一个问题:编译的过程和函数的代码-正常工作吗? 我还不知道 大量的代码已被移植和编译。 对于不包含上述练习类型的项目,这无疑是成功的。 但是测试代码的正确执行是一项艰巨的任务。 老实说,我没想到会遇到她。 我不会准备说我是否将在这个DBMS上有一个项目。 但是,如果这样做,那么将使用常规的便捷工具并定期迁移到Tibero,在Oracle上进行开发。 在IDE中编写代码而没有上下文提示并且界面本身存在周期性错误是一种低于平均水平的乐趣。

结论


Tibero在当前状态下是否有未来? 不知道 毕竟,如果您查看不包括超大型许可证的许可证成本,那么一个标准套接字的成本约为80万,这比Oracle便宜,但有时并非如此。 从我自己的经验中可以确信,到目前为止,这甚至离Oracle还很近。

使用现在提供的几乎免费的Tibero是否有意义? 也许是。 他们说,当支付技术支持的费用(一个插座每年99,000卢布)时,可以将其用于商业项目。 如果您有一个由甲骨文专家组成的团队,并且需要在服务器上创建并放置一些不太麻烦的东西,但又便宜又快捷-这是一个有趣的选择。 您仍然可以打制裁牌,告诉陷入困境的客户韩国不是美国。

我应该将现有项目从Oracle转换为Tibero吗? 没办法 没有理由寻求这样的冒险。 放弃Oracle技术支持而对任何人不付任何费用,会更容易。

如果需要为在Oracle上运行的旧项目创建新实例? 结果,购买新许可证? 在这里考虑一下。 您的基地可能会迁移并进行定性工作。 但是,请立即考虑支持该项目的两个领域,或者将所有内容翻译成Tibero。 我们考虑了廉价的许可证所带来的人工成本,风险和收益。 比较,决定。

也许在下一版的Tibero中,一切都会有所不同。 只需完成类型,制作普通的IDE或更改定价策略即可。 而且,如果DBMS与汽车相同,那么5年后,韩国人将占据重要的市场份额,并取代霸主。 我们会看到的。

聚苯乙烯


在为新项目选择DBMS时,TMaxSoft的技术支持是一项重要的任务。 我什至没有买一美元的许可证,这些家伙很快就回答了我,很感兴趣。 他们帮助解决了愚蠢的问题以及此处描述的问题。 反馈非常好。

Source: https://habr.com/ru/post/zh-CN413147/


All Articles