Oracle与PostgreSQL:一瞥

2020-05-04 20:35:38

我们在工作中面临着一些有趣的时刻,因为我们将在不久的将来开始改变我们的技术堆栈。我们的大多数Oracle流程将被Python取代,处理存储在拼花面板文件中的数据。对于必不可少的数据库进程,我们将改用PostgreSQL。我喜欢甲骨文,它为我们提供了很好的服务,但我对学习和使用新技术感到兴奋。这对我们来说是一个很好的机会,可以从一开始就参与构建一些东西,并在其他技术方面获得经验。

在第一次更广泛地了解PostgreSQL之后,我决定收集一些不同之处,并在本文中指出它们。我也计划在迁移过程中和迁移后分享我的经验。

我们经常使用的来自Oracle的DUAL表在PostgreSQL中不存在。不过别担心,你甚至可能会发现另一种方式更简单。

我真的很怀念Oracle的这一点,但幸运的是,PostgreSQL能够在对数据库对象运行DDL操作之前检查它是否存在。一些例子:

如果不存在,则创建TABLE TABLE_NAME(.。。。);如果存在表名称,则删除TABLE;如果存在表名称,则将ALTER TABLE重命名为新名称;如果存在列名称,则ALTER TABLE TABLE_NAME删除列;

我相信任何使用Oracle的人都经常在查询中使用(+)来简单地强制外部联接。在PostgreSQL中,我们没有这种“奢侈品”,所以我们必须采用默认方式。

假设您想要根据另一个表中的值更新表中的值。在Oracle中,我们通常使用子查询,但是在PostgreSQL中,有一种非常好的方法可以做到这一点。

与前面描述的UPDATE相同,在PostgreSQL中,当我们执行DELETE语句时,可以简单地使用另一个表中的值。

MERGE是一个有用且经常使用的语句,我们使用它来根据数据的存在来插入或更新数据。如果数据存在,我们将更新所需的列,如果不存在,则插入新记录。在PostgreSQL中,它称为UPSERT。在下面的示例中,如果名称列匹配,我们将插入新记录或更新电子邮件地址。

当匹配时,使用供应商b on(a.name=b.name)合并到客户a中,当不匹配时,更新设置a.email=b.email,然后插入(name,email)值(b.name,b.email);

将冲突(姓名)Do update set email=Customers.email;--通过EXCLUDED.Email插入客户(姓名,电子邮件)值(';[email protected]';)--通过EXCLUDED.email我们可以参考我们正在更新的";旧电子邮件值。

无论是在Oracle中还是在PostgreSQL中,如果存在匹配(冲突),我们都可以选择不执行任何操作。

在PostgreSQL中,表可以继承现有表的数据和/或结构。您可以将其视为面向对象编程中的类继承。

在甲骨文中,也有一种方法可以做类似的事情。但是,此解决方案仅创建表,没有任何其他对象,如索引或约束。新创建的表可能有数据,也可能没有数据,具体取决于条件。

上面的代码将基于Country表创建一个包含所有数据的新表。如果您只想要一个没有数据的空表,请执行以下命令:

与Oracle不同,Truncate在PostgreSQL中是事务安全的。这意味着如果将其放在BEGIN和ROLLBACK等事务语句中,截断操作将安全回滚。

PostgreSQL中不存在Oracle中常用的CONNECT BY-START WITH-PRICE子句。至少在默认情况下不是这样。通过安装tablefunc扩展,您可以拥有等效的功能。此外,在PostgreSQL中,您可以使用递归公用表表达式(CTE)来实现相同的结果。(Oracle中也提供CTE。)。您可以在这里找到更多带有示例的信息。

由于我们的团队在市场研究行业工作,海量数据通常需要分区表。让我们看一下关于如何按列表进行分区的以下示例。

创建表SALES(Salesman_id整数主键,Salesman_Name VARCHAR2(30),SALES_REGION VARCHAR2(30),SALES_DATE,SALES_AMOUNT整数)PARTION BY LIST(SALES_REGION)(PARTITION p_Asia VALUES(';India';,';China';),PARTION p_EUROUES VALUES(';France';,';UK';),分区p_america值(';USA';,';Canada';),分区p_rest value(默认值);

按列表(Sales_Region)创建表Sales(Salesman_id整数,Salesman_Name VARCHAR(30),Sales_Region VARCHAR(30),Sales_Date Date,Sales_Amount整数)分区;为(';India&39;,';China';)中的值创建Sales_p_Asia表Sales_p_Asia分区;为(';France';,';UK';)中的值创建表Sales_p_EURO PARTITION。为值在(';USA';,';Canada';);创建Sales_p_REST表Sales_p_REST PARTITION of Sales Default;创建表Sales_p_America PARTITION。

通常,我们将代码组织成块、过程或函数。让我们来看看它们的不同之处。

块、过程或函数的主体作为字符串文字传递。为了避免将代码编写为长字符串并转义所有单引号,PostgreSQL为我们提供了表示单引号的$$语法糖。但是,如果我们愿意,我们仍然可以使用单报价而不是$。对于过程和函数,语法差异也是相同的。你可以在这里和这里更深入地看一看。

PostgreSQL中没有包这样的东西。在与甲骨文共事多年之后,这可能需要一些时间才能习惯。但是,我们可以将包组织到单独的PostgreSQL过程和函数中。(就像Oracle包包含单独的过程和函数一样。)。通过使用标准命名约定,我们可以“克服”这一点,并通过从虚构的包名开始,后跟两个下划线来命名我们的过程和函数。

尽管需要强调的是,即使我们可以使用这种标准命名约定“组织”PostgreSQL过程和函数,但不幸的是,我们可能会忘记包级全局变量。

这些都是我一开始发现的有用的不同之处。随着我们将来开始迁移到PostgreSQL,我将分享我们的经验,并强调需要注意的事项。

我想我们不能说哪一个数据库更好,两个数据库都有自己的长处。至于性能,在我们完成迁移并开始使用PostgreSQL处理生产数据之后,我会知道更多。

如果您有任何意见,或者如果您有将Oracle PL SQL迁移到PostgreSQL的经验,请不要犹豫,请在评论中分享您的想法。我会很高兴,也很有兴趣听他们说。