从pg_depend和pg_class开始了解MogDB/openGauss/postgresql的系统元数据设计

前言

学习任何一种数据库,必须要了解它的数据字典,这样有利于了解数据库的结构、解读部分日志、定位一些问题。PG/OG系数据库的系统元数据遵从一个统一的设计规则,可以让初学者快速入门。本文以MogDB为例,剖析一下PG/OG系数据库的系统元数据设计哲学。

一、pg_depend

先来看pg_depend的表结构

名称类型引用描述
classidoidPG_CLASS.oid有依赖对象所在系统表的OID。
objidoid任意OID属性指定的依赖对象的OID。
objsubidinteger-对于表字段,这个是该字段的字段号(objid和classid引用表本身)。对于所有其它对象类型,目前这个字段是零。
refclassidoidPG_CLASS.oid被引用对象所在的系统表的OID。
refobjidoid任意OID属性指定的被引用对象的OID。
refobjsubidinteger-对于表字段,这个是该字段的字段号(refobjid和refclassid引用表本身)。对于所有其它对象类型,目前这个字段是零。
deptype“char”-一个定义这个依赖关系特定语义的代码。
n-不加cascade不删除,加cascade删除
a-加不加cascade都自动删除
i-加不加cascade都报错
e-表示是从插件创建的,不能删
p-初始创建的,objid都是0,只有refobj,也不能删

该表描述对象与对象之间的依赖关系,删除objid时,判断是否存在refobjid,并根据deptype的类型,来看此时应该进行的操作,主要为依赖的强弱性来看删除时是否要加cascade。

从这个表上可以看出,在PG/OG/MogDB中,对于对象的唯一性,是用classid+objid两个值来决定的,我们可以理解为java上的类和对象的概念,即先有类,然后基于类来创建对象。

原生PG在设计的时候,期望保持oid唯一(在一个db内),即一个oid就对应一个明确的对象。但按照这个结构发展这么多年,到了GaussDB后,某次增加一个函数的时候,错误地使用了已经在操作符里被用过的oid,导致后续OG系只能按照classid+objid两个信息来确定对象唯一性了,当然这并没有从内核上打破classid+objid唯一这个规则。有兴趣的可以比较一下这条SQL在PG和OG的输出差异

select refobjid,count(1) from
(select distinct refclassid,refobjid from pg_depend) 
group by refobjid having count(1)>1

classid均来自于pg_class.oid,我们先观察一下classid中的这些oid分别对应什么

image-xlch.png

pg_shdependpg_depend类似,但区别在于,pg_shdepend记录的是全局共享的依赖关系,是跨库的,比如用户和角色(pg_authid);而pg_depend只记录本库的。注意这两者之间不是包含关系。

regclass是一个"​对象标识符类型",可以将oid转换成对应在pg_class的名称(MogDB 5.2版本中新增了regroleregnamespace)。

可以看到这里的classid,在pg_class中对应的都是系统元数据表,即classid表示的每一个表,都是一种对象所属的类。

第二个字段objid,即为前面这个类下的一个对象id

我们任意取一笔记录,来看怎么找到这个对象

image-wpbx.png

该行记录的系统类为1255,可以查到对应pg_proc;

image-crxi.png

对象id为12560,那我们就去pg_proc里查oid=12560的记录,即可找到该对象是什么

image-atdc.png

以pg_depend进行管中窥豹,可以大致了解这些系统表的组织关系。

二、pg_class

pg_depend里这些classid都是pg_class的某一行的oid,包括pg_class这个表本身的oid,也是relname=’pg_class’这一行的oid。

但我们知道,pg_class里不是只有系统表的名称,还有普通表、视图、索引的名称也都会记录在里面,那么pg_class里到底会存哪些对象?

我们看下pg_class的表结构,由于该表的字段太多,本次我们只关注它有哪些对象,关键在relkind这个字段

relkind说明
r表示普通表
i表示索引
I表示分区表GLOBAL索引
S表示序列
L表示Large序列
v表示视图
c表示复合类型
t表示TOAST表
f表示外表
m表示物化视图

可以看到,这里的种类其实都拥有类似于表(或叫relation)的结构,即拥有多个字段,不过比较特殊的是索引和复合类型这两者,这两者不能通过sql语句直接查里面的数据,而复合类型本身更是没有数据内容

image-cxso.png

序列其实就是一张只有一行的表

image-eunx.png

在pg_attribute中,可以根据pg_class中的oid,查到该relation所包含的所有字段(包括隐藏字段和被删除字段),

也就是说,理论上,在MogDB中,下面这条SQL应该是查不出记录的(原生postgresql支持零列的表,但是仍然包含隐藏字段)

select * from pg_class c where not exists 
(select 1 from pg_attribute a where c.oid=a.attrelid);

pg_class中的每个oid(除了索引),都在pg_type中存在一条对应的记录,pg_class.oid=pg_type.typrelid

这意味着,每个relation自己,又都是各自的”类”,而relation里面的每行数据(tuple),是这个类的”对象”

至此,整个数据库中的所有数据,都是符合”类-对象”的特征

类层级对象层级对象
0-主类pg_class1-元数据表一个元数据表(比如pg_proc、pg_type)
1-元数据表pg_class2-对象(relation)一个relation(比如一个自建表、一个序列)
1-元数据表pg_proc2-对象(proc)一个函数(比如length、sum)
1-元数据表pg_type2-对象(type)一个数据类型(比如varchar、int)
2-对象(relation)一个自建表3-行(tuple)表的一行

三、系统元数据表清单

以上为MogDB/openGauss/postgresql的系统表元数据设计及其之间的逻辑关系,接下来我们看具体的元数据表,以下只列举一些常见的

表名ORACLE视图名扩展视图或扩展表备注
pg_databasedba_pdbs/sys.container$数据库列表
pg_collation字符排序规则
pg_conversion字符编码转换规则
pg_authiddba_users/sys.user$pg_user用户,pg_user隐藏了密码,加了用户级guc参数展示
pg_roles角色,按权限过滤展示
pg_auth_history历史密码变更记录
pg_auth_members继承角色关系
pg_group关联查询pg_auth_members
gs_db_privilegeany权限 (PG没有)
pg_default_acl新对象的默认权限(比如给schema下的新表默认查询权限)
pg_user_status用户状态(登录失败次数、密码过期)
pg_namespace模式(schema)
pg_classdba_tablespg_tables所有的表和类似表的对象(relation),都在pg_class中
dba_viewspg_views里面查询了pg_rewrite获取定义
pg_indexdba_indexex/dba_ind_columnspg_indexes索引
pg_constraintdba_constraint约束
pg_partitiondba_tab_partitionsdba_tab_subpartitions分区表和子分区表
pg_rewritepg_rules视图的定义在重写规则里,pg_rules只展示非select的规则
gs_matviewdba_mviewsgs_matview_dependency (物化视图依赖基表)物化视图 (PG没有)
pg_typedba_typespg_enum (枚举类型)注意create table或view时,会同时create一个同名的type
pg_range (范围类型)
pg_set (set类型, B 模式专用) (PG没有)
pg_attributedba_tab_colspg_attrdef (属性的默认值)针对pg_class中每个oid的属性(比如表的字段)
pg_description
pg_shdescriptionsh指在各个db中共享,比如pg_database表就是一个共享表
pg_procdba_procedurespg_aggregate (聚合函数)所有的function和procedure,包括package内的
pg_language支持的pg_proc语言
gs_packagegs_object (object-type,MogDB 5.2新增 )所有的package(PG没有)
pg_triggerdba_triggersDML触发器(含truncate)
pg_event_trigger事件触发器(比如ddl)
pg_extension扩展插件
pg_synonymdba_synonyms同义词(PG没有)
pg_foreign_serverdba_db_links外部服务器
pg_foreign_data_wrapper外部数据封装器
pg_foreign_table外部表
pg_dependdba_dependencies依赖关系
pg_shdepend共享依赖关系
pg_jobdbms_job 功能的相关表定时任务(PG没有)
pg_job_proc
gs_job_argumentdbms_schedule 功能的相关表定时任务(openGauss没放出sql函数接口)
gs_job_attribute
pg_operatorv$sqlfn_metadata操作符
pg_opclass操作符类
pg_opfamily操作符族
pg_cast类型转换
pg_am访问方法(hash、btree…)
pg_amop访问方法的操作符
pg_amproc访问方法调用的函数
pg_objectdba_objects所有对象(目前只包含以下)s 序列、l 大序列、v 视图、r 表、i 索引、P 存储过程、函数、S 包说明/object-type说明、B 包体/object-type体
pg_directorydba_directory数据库目录
pg_db_role_setting设置到数据库、用户级别的参数
pg_statistic统计信息
gs_dependencies_objgs_dependenciesplsql编译依赖关系(openGauss 6.0/MogDB 5.2新增)
pg_rlspolicy行级访问策略
pg_inherits继承表
gs_maskinggs_masking_policy动态脱敏(PG没有)
gs_masking_policy_actions
gs_masking_policy_filters

四、元数据表字段名设计

几乎所有的元数据表的字段名,都有一个特征,即有一个该表表名的三到四个字母缩写作为前缀。
比如pg_type表中的字段,是以typ开头,比如typnamespace、typname;
比如pg_proc表中的字段,是以pro开头,比如pronamespace、proname;
比如pg_attribute表中的字段,是以att开头,比如attrelid、attname;
有个特殊点的,pg_class,是以rel(即relation)开头,比如relnamespace、relname。
这种设计的好处是让所有的元数据字段能平面化,和内核一一对应,不存在一个属性名同时存在于多个地方。

五、总结

得益于postgresql这种严谨的设计,让所有内核开发者能遵循统一的规则来进行新功能的扩展;并且由于其极其简单明了的对象组织关系,让初学者也可以很快对数据库有个框架性的理解,只是千万不要死记硬背, 学习postgresql的优势在于,它几乎全部的功能都可以从表中查到,并且最终回到pg_class这个表上来。openGauss/MogDB继续延续这种设计,让国产数据库站在前辈们的肩膀上继续壮大。

  • 本文作者: DarkAthena
  • 本文链接: https://www.darkathena.top/archives/System-Metadata-Design-of-MogDB-openGauss-PostgreSQL-Starting-from-pg_depend-and-pg_class
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/468781.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[译] APT分析报告:13.Trellix对Iran网络空间能力评估

这是作者新开的一个专栏,主要翻译国外知名安全厂商的技术报告和安全技术,了解它们的前沿技术,学习它们威胁溯源和恶意代码分析的方法,希望对您有所帮助。当然,由于作者英语有限,会借助LLM进行校验和润色&am…

vue2,vue3,uniapp,小程序实现前端url生成二维码

最近遇到一个项目,api返回url地址,前端通过地址生成二维码。 话不多说直接上代码,亲测有效,希望能帮助大家,同时如果有更好的方法希望大家能够分享 1、第一步,在项目的utils文件夹下面创建一个weapp-qrco…

Python的函数(补充浅拷贝和深拷贝)

一、定义 函数的定义:实现【特定功能】的代码块。 形参:函数定义时的参数,没有实际意义 实参:函数调用/使用时的参数,有实际意义 函数的作用: 简化代码提高代码重用性便于维护和修改提高代码的可扩展性…

FPGA学习笔记#4 Vitis HLS 入门的第一个工程

本笔记使用的Vitis HLS版本为2022.2,在windows11下运行,仿真part为xcku15p_CIV-ffva1156-2LV-e,这一篇终于没有再大量使用别人的内容,是我自己从头捋到尾的结果,不过之后的笔记还是要参照别人的教程就是了。 学习笔记&…

Linux中给普通账户一次性提权

我在以前文章中Linux常见指令大全(必要知识点)-CSDN博客 写过sudo的概念与用法。其实本质就是提权用的但是在某些场景下就算提权了也不能使用。 例如:打开主工作目录 他不相信你这个用户,虽然你是erman 解决方法 使用root账号打开…

A027-基于Spring Boot的农事管理系统

🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 赠送计算机毕业设计600…

linux命令详解,存储管理相关

存储管理 一、内存使用量,free free 命令是一个用于显示系统中物理内存(RAM)和交换空间(swap)使用情况的工具 free -m free -m -s 5参数 -b 功能: 以字节(bytes)为单位显示内存使用情况。说…

关于若依500验证码问题的求助

关于若依框架中验证码出现500错误的问题,这通常表示服务器内部错误。以下是一些可能的原因及解决方案: 一、配置文件问题 .env.production文件: 确保.env.production文件中的VUE_APP_BASE_API已经修改成服务器上的域名地址,而不…

HashMap(深入源码追踪)

一篇让你搞懂HashMap的几个最重要的知识点,往源码跟踪可以让我们很轻松应对所谓的一些八股面试题. 一. 属性解释 先来解释HashMap中重要的常量属性值 DEFAULT_INITIAL_CAPACITY : 默认初始化容量,也就是如果不指定初始化的Map存储容量大小,默认生成一个存储16个空间的Map集合…

2024年第四届“网鼎杯”网络安全比赛---朱雀组Crypto- WriteUp

2024年第四届“网鼎杯”网络安全比赛---朱雀组Crypto-WriteUp Crypto:Crypto-2:Crypto-3: 前言:本次比赛已经结束,用于赛后复现,欢迎大家交流学习! Crypto: Crypto-2: …

【代码随想录day22】【C++复健】77. 组合;216.组合总和III; 17.电话号码的字母组合

77. 组合 这题做完之后还是有一种稀里糊涂的感觉。思考了半天什么范围合理,并且怎么设置才能让这个范围合理,然而一看答案,发现答案完全没考虑这些因素,直接暴力全遍历了。只能说确实这样能够放弃思考,比较省心一些.…

solidworks默认模板无效/打开step文件为空白 不显示模型

①打开step文件时如下提示: 是由于sw模版没有设置好 解决方法: 把零件和装配体模版选一下,gb_part和gb_assembly 再打开文件就不会有提示了。 ②打开step文件为空白 不显示模型 文件未损坏且sw版本正确情况下, 首先尝试按F&…

easyexcel实现自定义的策略类, 最后追加错误提示列, 自适应列宽,自动合并重复单元格, 美化表头

easyexcel实现自定义的策略类, 最后追加错误提示列, 自适应列宽,自动合并重复单元格, 美化表头 原版表头和表体字体美化自动拼接错误提示列自适应宽度自动合并单元格使用Easyexcel使用poi导出 在后台管理开发的工作中,离不开的就是导出excel了. 如果是简单的导出, 直接easyexce…

微深节能 煤码头自动化翻堆及取料集控系统 格雷母线

一、系统概述 微深节能在煤码头自动化翻堆及取料集控系统中引入了格雷母线高精度位移测量系统,该系统是一项重要的技术创新,显著提升了煤码头作业的自动化水平和精确性。它主要用于实现对斗轮堆取料机等大型机械设备的精准定位和自动化控制,从…

LeetCode 热题100 之 栈

1.有效的括号 思路分析&#xff1a;我们可以使用栈&#xff08;stack&#xff09;来解决这个问题。栈是一种先进后出的数据结构&#xff0c;这与括号匹配的需求非常契合。 unordered_map<char, char> bracket_map&#xff1a;这个哈希表用来存储右括号与左括号的对应关系…

yolov11-seg数据集制作训练推理流程:

文章目录 前言一、数据集制作二、模型训练推理&#xff1a; 前言 随着深度学习技术的不断发展&#xff0c;目标检测与分割技术在计算机视觉领域扮演着越来越重要的角色。YOLO&#xff08;You Only Look Once&#xff09;作为一种高效、实时的目标检测算法&#xff0c;自提出以…

基于Spring Boot的乡政府管理系统设计与实现,LW+源码+讲解

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装乡政府管理系统软件来发挥其高效地信息处理的作用&#xf…

python的学习

0.tips 1.变量命名规则 2.变量的赋值 3.变量的类型 int&#xff0c;float&#xff0c;str&#xff08;双引号、单引号、三引号包含都可以&#xff09; 类型带来的意义 动态类型的基本特性 4.注释 5.控制台 格式化字符串f-string 输入/输出input 6.运算符 算术运算符 //&…

信息安全工程师(79)网络安全测评概况

一、定义与目的 网络安全测评是指参照一定的标准规范要求&#xff0c;通过一系列的技术、管理方法&#xff0c;获取评估对象的网络安全状况信息&#xff0c;并对其给出相应的网络安全情况综合判定。其对象主要为信息系统的组成要素或信息系统自身。网络安全测评的目的是为了提高…

【GoWeb示例】通过示例学习 Go 的 Web 编程

文章目录 你好世界HTTP 服务器路由&#xff08;使用 gorilla/mux&#xff09;连接到 MySQL 数据库MySQL 数据库简单操作模板静态资源和文件操作表单处理中间件&#xff08;基础&#xff09;中间件&#xff08;高级&#xff09;会话JSONWebsockets密码哈希 你好世界 Go语言创建…