PostgreSQL之系统对象介绍

2020-06-17 00:00:00 函数 语言 语法 兼容 符合

近和很多人(阿里的,腾讯的,。。。)聊PostgreSQL,发现大家对于PG大的认同点是他的词法分析和语法分析做的非常好,认为是替代Oracle的佳方案。 本人开始接触PostgreSQL开发,便是做的兼容。经过多年的学习,比较认同新手接触PostgreSQL可以先通过系统函数、语法等方式入手。 讨论了许多,正好将自己对于这方面的了解整理一下,也算对自己当年有个交代。 产品的兼容代码由于是商业秘密,在这里无法公开,这里会以PostgreSQL已有内容或开源代码进行介绍实现方式。

按照惯例,先上一张思维导图,以下是本文所讲述内容的概述:

本文首先对兼容做一下阐述,然后对PostgreSQL的系统对象进行介绍,在这里将系统对象拆分为对象、语法以及共享组件。

为什么要做兼容

PostgreSQL本身就有很完善的SQL体系,为什么要做兼容?尤其是为什么要做Oracle的兼容? 主要的原因我认为是Oracle经过多年的市场耕耘,造就了一大批基于Oracle的开发人员。 目前市场上很多应用都是基于Oracle开发的。这就对数据库迁移产生了非常大的阻碍。 国内这几年一直在喊去IOE,但是效果了了。从亚马逊完成Oracle迁移后,进行庆功就很能说明其难度之大。 迁移的不仅仅是数据库,而是整个数据库生态。从应用端开发,到数据库管理,都需要做出改变。 同时,在这里不得不说一下Oracle确确实实在数据库生态方面做了非常多的工作,其他数据库难以望其项背。 为什么要做兼容?尤其是Oracle兼容? 因为目前PostgreSQL在国内的推广程度较小,酒香其实也怕巷子深。可以通过兼容Oracle扩大市场,推广PostgreSQL。 其次,Oracle成功有他的道理,他的生态是非常的完善。向达者学习也是值得去做的。 如果完成了Oracle兼容,那么我们可以做到:

  1. 更快、更好地应用迁移;
  2. 完成部分机构的数据库要求;
  3. 减少新语法的学习成本;
  4. 完成数据库生态。

兼容级别

那么如果我们要做兼容,那么应该怎么做? 兼容也不一定是一味的完全一模一样,重复造轮子是没有价值的。 我将兼容级别划分为三类:

  1. 完全相同,使用方法和功能完全一致,终达到用户不需要改动任何应用程序,即可使用;
  2. 部分相同,使用方法一致,但实现的功能有部分不同,可以针对用户需求完成功能,减少时间消耗;
  3. 完全不同,实际解决的问题相同,但使用方法不相同,Oracle有很多功能是基于其整体架构的,所以如果想这部分内容,成本非常大,但不如找到根本问题,通过其他方法解决。

这三种级别也不是完全独立的,我们可以有选择性地对兼容内容进行不同级别的兼容开发。比如系统函数我们就可以做的一模一样,而部分类型可以选择部分兼容。

兼容开发方式

我们有以下2种方式开发兼容功能: 完全开发,组织团队,根据需求或者Oracle官方文档(这里吐槽一下,实际使用可能存在比文档展示的方法更多)一一对比,完全实现。 部分开发,基于开源组件二次开发(比如Orafce),或者购买EDB动态库或者兼容代码(资金雄厚的尽可能选择此类)。

系统对象

对象

系统对象主要为下图内容,这些内容基本上已经在orafce中包含了:

系统表

需要增加table.h和table.dat。

  • 头文件是表定义以及宏定义,可参看src/include/catalog/pg_class.h。
  • dat文件为表内容,这部分可以使用dat初始化赋值或者SQL语句赋值,可参看src/include/catalog/pg_class.dat。

系统视图

可参看src/backend/catalog/system_views.sql:

CREATE VIEW pg_roles AS
    SELECT
        rolname,
        rolsuper,
        rolinherit,
        rolcreaterole,
        rolcreatedb,
        rolcanlogin,
        rolreplication,
        rolconnlimit,
        '********'::text as rolpassword,
        rolvaliduntil,
        rolbypassrls,
        setconfig as rolconfig,
        pg_authid.oid
    FROM pg_authid LEFT JOIN pg_db_role_setting s
    ON (pg_authid.oid = setrole AND setdatabase = 0);

相关文章