探討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對應的數據文件也是獨立存放的。

結論

  1. 在PG中;同實例下每個數據庫是完全獨立;表是在存放在同庫名的catalog下;例如Postgres數據庫的表存放在Postgres的catalog下,可以把catalog理解為database。同時物理結構是也是獨立存放的
  2. 每個 database 創建時;會默認為庫創建pg_catalog/information_schema

最后,前面的疑問“PostgreSQL實例中數據庫之間的關系,以及數據庫和對象的關系”,應該很好解釋清楚。

參考文獻

https://www.postgresql.org/docs/current/catalogs.html

https://www.postgresql.org/docs/current/infoschema-schema.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM