探讨PostgreSQL实例中数据库之间的关系
疑问
前几天PG学习微信群有人在问“pg_class 存储了对象和命名空间,表空间的对应关系,为什么没有和数据库的关系?我想查数据库下面有多少对象,找不到数据库和对象的关系?”
简而言之;PostgreSQL数据库和对象的关系;提这个问题的同学;应该是想知道
PostgreSQL实例中数据库之间的关系,以及数据库和对象的关系。
至于能否有这样的SQL;容我一步一步探索
探索
1、探索PG的逻辑结构
逻辑结构图
上图解析:
- 第一层是实例(Instance)。
- 第二层是数据库(Database);一个实例下有多个数据库;每个数据库之间是完全独立的。
- 第三层是Schema;数据库下面有多个Schema;其中“public” 是数据库创建时产生的。
- 每个Schema下面可以创建表,视图,索引,函数,序列,物化视图,外部表等等。
由于在PostgreSQL每个数据库是完全独立的;这可以解释另外一个问题(为什么访问同一个实例下其他数据库为什么要借用dblink或者fdw接口?)。
这时可能会有学MYSQL同学会问到;(为什么在MYSQL中可以访问同实例下其他数据库?)。其实MYSQL跟PostgreSQL逻辑结构不一样;其中MYSQL实例中的数据库相当于PostgreSQL上图的第三层的Schema。
2、探索PG数据库中schema
了解过PostgreSQL的同学都知道;我们通过系统表pg_database可以查到数据库,通过系统表pg_class可以查到数据库object。
postgres=# select datname, oid from pg_database where datname = 'postgres';
datname | oid
----------+-------
postgres | 13543
(1 row)
postgres=# select relname, oid from pg_class where oid = 't1' :: regclass;
relname | oid
---------+-------
t1 | 32768
(1 row)
而pg_database、pg_class存放在一个名为pg_catalog的Schema下。其中pg_catalog是系统级的schema,用于存储系统函数和系统元数据、而每个 database 创建好后,默认会有3个Schema。
- 一个名为pg_catalog,用于存储Postgresql系统自带的函数,表,系统视图,数据类型转换器以及数据类型定义等元数据
一个名为information_schema,用于存储所需求提供的元数据查询视图,目的是以符合ANSI SQL规范,可单独删除
- 一个名为public,用于存储用户创建的数据表。不建议项目的表存放在public下,1、是数据安全;2、表存放混乱;不利于后期维护等等
查看schema
-- 通过元命令查看
lottu=# \dn
List of schemas
Name | Owner
--------+----------
public | postgres
-- 查看隐藏的schema
lottu=# select table_schema
lottu-# from information_schema.tables
lottu-# group by table_schema;
table_schema
--------------------
information_schema
pg_catalog
(2 rows)
-- 系统表存放的schema是在pg_catalog下;
lottu=# \d pg_catalog.pg_class
lottu=# \d pg_catalog.pg_database
--这里我们先抛出一个问题;后面解析;每个数据库的pg_class是同一个吗?
3、探索PG数据库中catalog
我们知道新建一个数据库会在表空间对应的目录下创建一个 oid(数据库oid)的目录;用于存放这个数据库对应的数据库文件。
-- 例如数据库lottu
lottu=# select oid, datname from pg_database where datname='lottu';
oid | datname
-------+---------
32771 | lottu
(1 row)
--对应的目录就会有一个32771的文件夹
[postgres@node3 ~]$ ll /data/postgres/data/base/
total 32
drwx------. 2 postgres postgres 4096 Sep 16 10:54 1
drwx------. 2 postgres postgres 4096 Sep 16 10:54 13542
drwx------. 2 postgres postgres 12288 Sep 21 11:44 13543
drwx------. 2 postgres postgres 12288 Sep 21 14:33 32771
-- 在 数据库lottu中;其中的table_catalog
lottu=# select table_catalog
lottu-# from information_schema.tables
lottu-# group by table_catalog;
table_catalog
---------------
lottu
(1 row)
-- 在数据库 postgres中;其中table_catalog是postgres。
lottu=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=# select table_catalog
from information_schema.tables
group by table_catalog;
table_catalog
---------------
postgres
(1 row)
通过上述实验;我们可以了解到PG同实例下数据库之间不仅物理结构完全独立,逻辑结构也是完全独立。这个不仅作用于用户表,还作用于系统表。现在来解析上面抛出的问题“每个数据库的pg_class是同一个吗”?
-- 在postgres数据库中
postgres=# select table_catalog, table_schema, table_name, table_name :: regclass ::oid from information_schema.tables where table_name = 'pg_class';
table_catalog | table_schema | table_name | table_name
---------------+--------------+------------+------------
postgres | pg_catalog | pg_class | 1259
(1 row)
--在 lottu 数据库中
lottu=# select table_catalog, table_schema, table_name, table_name :: regclass ::oid from information_schema.tables where table_name = 'pg_class';
table_catalog | table_schema | table_name | table_name
---------------+--------------+------------+------------
lottu | pg_catalog | pg_class | 1259
(1 row)
--根据oid找到文件
[postgres@node3 data]$ find . -name '1259*'
./base/1/1259
./base/1/1259_vm
./base/1/1259_fsm
./base/13543/1259
./base/13543/1259_vm
./base/13543/1259_fsm
./base/13542/1259
./base/13542/1259_vm
./base/13542/1259_fsm
./base/32771/1259
./base/32771/1259_vm
./base/32771/1259_fsm
结果:
- 在逻辑结构上;同实例下每个数据库的表是在存放在同库名的catalog下。
- 在物理结构上;同实例下每个数据库的pg_class对应的数据文件也是独立存放的。
结论
- 在PG中;同实例下每个数据库是完全独立;表是在存放在同库名的catalog下;例如Postgres数据库的表存放在Postgres的catalog下,可以把catalog理解为database。同时物理结构是也是独立存放的
- 每个 database 创建时;会默认为库创建pg_catalog/information_schema
最后,前面的疑问“PostgreSQL实例中数据库之间的关系,以及数据库和对象的关系”,应该很好解释清楚。
参考文献
https://www.postgresql.org/docs/current/catalogs.html
https://www.postgresql.org/docs/current/infoschema-schema.html
探讨PostgreSQL实例中数据库之间的关系的更多相关文章
- oracle里实例和数据库之间的关系
一个数据库服务器上可以装几个数据库它们都是用sid来标志,例如orcl1,orcl2,orcl3等等,一个数据库如orcl1中可以有多个实例吗? Oracle数据库,实际上应该是说,我们使用的是Ora ...
- RDBMS与数据库之间的关系
什么是数据库? 数据库就是用来存放数据的仓库,它是一种特殊的文件. 什么是关系型数据库? 关系型数据库就是指建立在关系模型基础上的数据库,通常由多张表组成,这些表之间存在一定的关系. 什么是RDBMS ...
- 持续集成:TestNG中case之间的关系
持续集成:TestNG中case之间的关系 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq: ...
- [转]oracle 数据库、表空间、实例、服务之间的关系
1.每个DATABASE--可包含多个INSTANCE--每个INSTANCE可包含多个TABLESPACE和USER等(授予USER读写TABLESPACE的权限)--每个TABLESPACE可包含 ...
- JS 之原型,实例,构造函数之间的关系
JS是面向对象的语言,函数也是对象.下面大致介绍下实例,原型与构造函数之间的关系. 构造函数模式 function Person(name,age){ this.name = name; this.a ...
- Spring基础——在 IOC 容器中 Bean 之间的关系
一.在 Spring IOC 容器中 Bean 之间存在继承和依赖关系. 需要注意的是,这个继承和依赖指的是 bean 的配置之间的关系,而不是指实际意义上类与类之间的继承与依赖,它们不是一个概念. ...
- CSS系列:CSS中盒子之间的关系
1. 标准文档流 标准文档流是值在不使用其他的雨排列和定位相关的特殊CSS规则时,各种元素的排列规则. 1.1 块级元素(block level) 块级元素不会排在同一行中,总是以一个块的形式表现出来 ...
- oracle数据库实例,数据库的理解
转自http://www.cnblogs.com/advocate/archive/2010/08/20/1804066.html 加深一下理解 数据库就是一个相片底片 实例就是相纸 一个底片可以冲多 ...
- Oracle实例和数据库区别
什么是数据库,其实很简单,数据库就是存储数据的一种媒介.比如常用的文件就是一种,在Oracle10G中,数据的存储有好几种.第一种是文件形式,也就是在你的磁盘中创建一批文件,然后在这些文件 ...
随机推荐
- 编译原理LR(0)项目集规范族的构造详解
转载于https://blog.csdn.net/johan_joe_king/article/details/79051993#comments 学编译原理的时候,感觉什么LL(1).LR(0).S ...
- java+opencv实现图像灰度化
灰度图像上每个像素的颜色值又称为灰度,指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0.所谓灰度值是指色彩的浓淡程度,灰度直方图是指一幅数字图像中,对应每一个灰度值统计出具有该灰 ...
- PhpStorm安装及破解流程
下载完以后,把破解的jar包放到bin目录下,更改两个.vmoptions文件 我是安装了一个破解的和汉化包 jet是破解包,resource是汉化包,然后还要修改本地主机地址 例: 0.0.0.0 ...
- Combine 框架,从0到1 —— 2.通过 ConnectablePublisher 控制何时发布
本文首发于 Ficow Shen's Blog,原文地址: Combine 框架,从0到1 -- 2.通过 ConnectablePublisher 控制何时发布. 内容概览 前言 使用 ma ...
- 力扣Leetcode 198. 打家劫舍
打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定 ...
- 力扣Leetcode 11. 盛最多水的容器
盛最多水的容器 给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找 ...
- 用java中的Arraylist实现电话本系统管理
大致思路:创建一个电话本条目的类,在主类中实例化.用实例化的对象调用构造参数接收输入值,然后将此对象存入Arraylist的对象中,实现动态添加电话本条目. 该系统具备添加.删除.修改.查询所有和按姓 ...
- 在Spring中拦截器的使用
Filter Filter是Servlet容器实现的,并不是由Spring 实现的 下面是一个例子 import java.io.IOException; import javax.servlet.F ...
- 沈阳做假证z
沈阳做假证[电/薇:187ヘ1184ヘ0909同号]办各类证件-办毕业证-办离婚证,办学位证书,办硕士毕业证,办理文凭学历,办资格证,办房产证不. 这是一个简单的取最大值程序,可以用于处理 i32 数 ...
- WebStorm下ReactNative代码提示设置
ReactNative 代码智能提醒 (Webstrom live template) https://github.com/virtoolswebplayer/ReactNative-LiveTe ...