首页 > 编程知识 正文

数据库对象包括哪些(面向对象数据库系统)

时间:2023-05-03 07:47:04 阅读:88352 作者:3879

kydds

中国PG分会认证专家

OstgreSQL资深内核开发工程师。 他为完整的数据库加密、Oracle兼容功能、PostgreSQL监视工具、PostgreSQL即时编译等做了很多工作。

1前言

最近,和很多人(阿里的、腾讯的……)聊起PostgreSQL,发现大家对PG最大的认同点是他的词法分析和语法分析做得非常好,是取代Oracle的最佳方案。 我最开始接触PostgreSQL开发是兼容的。 经过多年的学习,初学者接触PostgreSQL被认为可以首先通过系统函数、语法等方法开始。 讨论了很多,正好整理了自己对这方面的了解,就成了对自己当时的说明。 由于产品的兼容代码是商业机密,所以不能在此公开。 下面介绍如何在PG的现有内容或开源代码中实现。

按照惯例,从前面的思维导图开始。 以下是本文要说明的内容概要。

本文首先介绍兼容性,然后介绍PostgreSQL系统对象。 在本例中,我们将系统对象分割为对象、语法和共享组件。

2为什么兼容

明明PostgreSQL本身有完美的SQL体系,为什么要做兼容性? 特别是为什么要做Oracle的兼容性? 我认为最主要的原因是,Oracle经过多年的市场努力,产生了大量基于Oracle的开发者。 目前,市场上的许多APP都是基于Oracle开发的。 这给数据库的迁移带来了非常大的障碍。 国内这几年在呼唤IOE,很有效果。 从亚马逊迁移到Oracle完成后,进行庆功很好地展示了难度之高。 迁移的不仅仅是数据库,还有整个数据库的生态。 从APP端的开发到数据库管理,需要进行变更。 同时,这里不得不说Oracle确实在数据库生态方面做了非常多的工作,其他数据库很难看到其项目。 为什么兼容? 特别是与Oracle的兼容性如何? 现在,由于PostgreSQL在国内的普及度很小,酒的香味其实也很怕巷子深。 通过与Oracle的兼容性,可以扩大市场,推进PG。 其次,Oracle的成功有他的道理,他的生态非常完善,也值得学习。 与Oracle的兼容性完成后,您可以:

更快、更高效地应用迁移,降低新语法的学习成本,以满足某些机构的数据库需求,从而实现数据库生态化。 3兼容性级别

那么,如何取得兼容性呢? 互换性也不一定只是一模一样,重复制造车轮也不值得。 将兼容性级别分为三类。

同样,使用方法和功能完全一致,最终用户无需更改APP即可使用。部分相同,使用方法一致,但实现的功能部分不同,可以根据用户的需要完成功能,减少时间消耗完全不同。 虽然实际解决的问题相同,但是使用方法不同。 由于Oracle有很多基于其整体体系结构的功能,所以考虑到这部分的内容,成本非常高,但是最好找出根本问题,用其他方法解决。 这三个级别也不是完全独立的,可以选择性地对兼容的内容进行不同级别的兼容开发。 例如,系统函数可以制作得一模一样,但有些类型可以选择部分兼容性。

4兼容开发方式

开发兼容功能有两种方法: 一个是完全开发,组织团队,逐一比较需求和Oracle的官方文档(在这里吐槽一下,实际使用方法可能比文档中所示的方法多) ),然后完全实现。 二是部分开发,基于开源组件进行二次开发,或者购买EDB动态库或兼容代码(有资金的尽可能选择这种)。

5系统对象

对象

系统对象主要是下图的内容,这些内容基本上包含在orafce中。

系统表

需要添加table.h和table.dat

头文件是表定义和宏定义,请参见src/include/catalog/pg_class.h。 dat文件是表的内容,这部分可以使用dat初始化赋值或SQL语句赋值。 请参见src/include/catalog/pg _ class.dat文档。 系统视图

请参见src /后端/目录/系统视图. SQL。

内部函数

内部c语言函数的实现:以gram_checker为例,该函数可以对参数进行SQL分析,每次执行一个SQL,成功后返回空值,发生错误时提示详细的错误消息。 src /后端/实用程序/添加/图表检查器. c :

src /包括/目录/pg _ proc.dat :

内部SQL函数的实现:

实现SQL函数(

考:postgresql.org/docs/cur):

其他语言函数实现:plpgsql(可参考:postgresql.org/docs/cur):

plv8(可参考:pgxn.org/dist/plv8/doc/):

操作符

C语言实现:src/include/catalog/pg_operator.dat:

SQL实现(可参考:postgresql.org/docs/12/):

类型

C语言定义 src/include/catalog/pg_type.dat:

SQL定义(可参考 postgresql.org/docs/12/):

Domain实现(可参考 postgresql.org/docs/cur):

语法映射 src/backend/parser/gram.y:

内部逻辑修改:将numeric变为int4或int8:

隐式转换

C语言实现 src/include/catalog/pg_cast.dat:

SQL定义(参考 postgresql.org/docs/cur):

package

参考:github.com/orafce/orafc:

6共享组件

共享组件提供一系列的工具共数据库管理使用,旨在提高数据库管理便宜性。比如AWR(Automatic Workload Repository),能够提供更多的数据库监控信息,供DBA使用,快速定位、解决数据库问题。迁移工具:完成数据结构、数据迁移以及存储过程、函数转换。此类内容对于数据库迁移或者应用开发影响甚小,其作用主要在于便于数据库迁移、管理。内容非常多,这里就不一一列举了。

7语法

语法,也就是我们常说的SQL,主要涉及到的内容是编译原理。PostgreSQL使用Flex和Bison两个工具完成的语法实现。Flex和Bison是Linux下两个用来生成程序的工具,可以处理结构化输入,它们生成的程序分别叫做词法分析器和语法分析器,他们一般结合使用来处理复杂的文件解析工作,在PostgreSQL中主要是用来生成SQL语句的词法和语法分析器。

Flex & Bison

Flex(快速词法分析器生成器)是lex的免费开源软件替代品。它是生成词法分析器(也称为“扫描器”或“词法分析器”)的计算机程序。它可以利用正则表达式来生成匹配相应字符串的C语言代码,其语法格式基本同Lex相同。经常连同Yacc或GNU Bison一起使用。Postgresql 中的Flex 文件为scan.l,通过Flex编译为scan.c。

Bison是一种通用解析器生成器,它将带注释的上下文无关文法转换为使用LALR(1)解析器表的确定性LR或广义LR(GLR)解析器 。作为一项实验性功能,Bison还可以生成IELR(1)或规范的LR(1)解析器表。一旦您精通Bison,就可以使用它来开发各种语言解析器,从用于简单台式计算器的语言解析器到复杂的编程语言。Bison与Yacc向上兼容:所有正确编写的Yacc语法都应与Bison一起使用,而无需进行任何更改。熟悉Yacc的任何人都应该可以轻松使用Bison。您需要精通C或C ++编程才能使用Bison。还支持将Java作为实验功能。Postgresql 中的Bison 文件为gram.y,通过Bison编译生成gram.h,gram.c。

Flex

Flex由三部分组成

定义部分%%规则部分%%用户附加的C语言部分

请参看:https://zhuanlan.zhihu.com/p/89473441(kydds知乎专栏:Flex介绍)

Bison

Bison由三部分组成

定义部分%%规则部分%%用户附加的C语言部分

请参看:https://zhuanlan.zhihu.com/p/89479111(kydds知乎专栏:Bison介绍)

PostgreSQL中语法工作各个文件之间的调用关系:

scan.l:词法分析器在文件,定义词法结构,编译生成scan.cgram.y:语法分析器在文件,定义语法结构,编译生成gram.c和gram.h;parser.c:raw_parser函数,主要通过调用生成的base_yyparse函数来实现词法分析和语法分析的工作。kwlist.h:SQL关键字定义,注意:关键字名要小写,按照字符串值顺序定义kwlookup.h:定义结构体ScanKeyword;kwlookup.c:使用kwlist.h初始化关键字数组ScanKeywords,提供ScanKeywordLookup函数scanup.c:提供几个词法分析时常用的函数。

下面以SQL,select oid,relname from pg_class where relname='pg_class';为例,说明一下语法解析过程:首先看一下SQL,

我们将SQL转化为语法分析树:

scanner发现起始位置为‘select’,并确认为关键字SELECT,返回token值与数值;parser接收到scanner的返回值,将‘select’移进,发现属于stmtblock->stmtmulti->stmt->SelectStmt->select_no_parens->simple_select;scanner发现oid,relname符合移进条件opt_target_list;符合移进条件target_list;其中oid在simple_select符合移进条件target_list->target_el->a_expr->c_expr->columnref->Colld->IDENT,即移进,这时发现符合归约条件target_el,即归约,返回target_el=oid;其中relname在simple_select符合移进条件target_list->target_el->a_expr->c_expr->columnref->Colld->IDENT,即移进,这时发现符合归约条件target_el,即归约,返回target_el=relname;target_el=oid,target_el=relname归约符合target_list,即归约;target_list符合归约条件opt_target_list,也进行归约。scanner发现from,移进from未符合归约条件,继续移进pg_class,符合from_list->table_ref->relation_expr->qualified_name->ColId->IDENT,符合归约条件,则返回from_list;scanner发现where符合移进条件where_clause,移进where未符合归约条件,继续移进,发现符合移进条件a_expr;发现符合移进条件a_expr '=' a_expr;继续移进relname,符合a_expr->c_expr->columnref->Colld->IDENT,符合归约条件,则返回a_expr;继续移进‘pg_class’,符合a_expr->c_expr->AexprConst->Sconst->SCONST,符合归约条件,则返回a_expr;符合归约条件,返回where_clause;发现符合归约条件,返回simple_select;发现符合归约条件,返回select_no_parens,SelectStmt,stmt,stmtmulti,stmtblock。

8语法能做什么

语法增删改

我们可以在原有的语法体系上增删改语法,增加兼容语法。甚至可以增加多个语法解析器来对不同的数据库进行兼容。

语法模块化

可以考虑将SQL解析器从PostgreSQL代码中单独摘出来作为工具或者库文件,这样可以使用其进行迁移语法检测、异构数据库语法转化、SQL转发。甚至可以基于此进行完成异构数据库语法兼容。

Grammar_checker

最近完成了一个语法检测工具,Grammar_checker:

JIT

利用LLVM对SQL查询计划进行优化。随着现在存储技术的发展,尤其是内存、ssd硬件的发展,以及存储结构,如列存,如分布式,I/O瓶颈逐渐的在降低,而带来的影响就是cpu的瓶颈来了。很多人可能会问cpu有什么瓶颈?现代数据库为了完成更多的用户操作,有很多的冗余操作。比如我们即便向数据库输入一个常量,数据库还是首先以字符串的形式拿过来,进行处理,经过很多步骤后,确认是常量,然后放入相应位置。这中间就出现了很多人工就能减少的步骤,而数据库或者计算机是不得而知的。Llvm是一款编译器后端。他能将程序语言转化为自己的中间语言,然后进行优化。它主要的作用就是减少cpu的指令数量,以及提高cpu cache利用率。如何理解llvm,如果大家了解java的话,可能就对JIT不陌生了。我们的Java之所以能够一次编程,处处运行,就是因为我们的JDK就是一个解释器。所有的java程序,都经过编译,编译为class文件。这个可以理解为java语言与机器语言的中间语言。而jdk可以将这中间语言重新解释,并优化为机器码,从而进行执行。pg现有的JIT技术也是相同的方式进行的。不同点在于,这里使用的是llvm作为中间语言的编译和解释、优化再执行。

大体步骤如图所示:

其优化原理以及位置如下:

它是通过LLVM将查询计划转化为LLVM中间语言,然后对中间语言进行优化,减少冗余的指令集并提高cpu Cache的利用率。

9写在最后

以上就是我坚定的枕头工作的知识总结,希望对初学PostgreSQL的人有所帮助。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。