下載吧 - 綠色安全的游戲和軟件下載中心

          軟件下載吧

          當前位置:軟件下載吧 > 技術開發 > 數據庫 > PostgreSQL數據庫中跨庫訪問解決方案

          PostgreSQL數據庫中跨庫訪問解決方案

          時間:2024-02-24 17:17作者:下載吧人氣:20

          PostgreSQL跨庫訪問有3種方法:Schema,dblink,postgres_fdw。

          方法A:在PG上建立不同SCHEMA,將數據和存儲過程分別放到不同的schema上,經過權限管理后進行訪問。

          方法A的示例如下:

          測試1(測試postgres超級用戶對不同schema下對象的訪問)

          查看當前數據庫中的schema

           postgres=# dn

           List of schemas

           Name | Owner

          ——————-+———

          dbms_job_procedure | postgres pgagent | postgres

           postgres | postgres

           public | postgres

           (4 rows)

          (當前連接數據庫的用戶為postgres)

          postgres=# select user;

          user

          ———-

          postgres

           (1 row)

          創建名為test1的schema

           postgres=# create schema test1;

           CREATE SCHEMA

          創建模式test1下的對象,表ticket1

           postgres=# create table test1.ticket1(id int);

           CREATE TABLE

          可以看到并沒有我們之前建立的表

           postgres=# d

          List of relations

           Schema | Name | Type | Owner

          ————————-+———

          public | dept | table | postgres

           public | emp | table | postgres

           public | jobhist | table | postgres

           public | next_empno | sequence | postgres

           public | salesemp | view | postgres

           (5 rows)

          在對象前加schema,postgres用戶可以訪問ticket1表

          postgres=# select * from test1.ticket1;

          id

          ————————————————-

          (0 rows)

          查看模式 搜索路徑

           postgres=# show search_path ;

           search_path

          —————-

          “$user”,public

           (1 row)

          把創建的模式test1添加到模式搜索路徑

          postgres=# set search_path to “$user”,public,test1;

           SET

           postgres=# show search_path ;

           search_path

          ————————

          “$user”, public, test1

           (1 row)

           為了訪問方便,在搜索路徑中添加schema對象之后既可以看到該模式下的表,也可以直接進行搜索,而不用添加schema前綴。(這里因為是超級用戶,所以不用給postgres賦權,如果是普通用戶,想要訪問,需要賦權)

           postgres=# d

          List of relations

           Schema | Name | Type | Owner

          ————————-+———

          public | dept | table | postgres

           public | emp | table | postgres

           public | jobhist | table | postgres

           public | next_empno | sequence | postgres

           public | salesemp | view | postgres

           test1 | ticket1 | table | postgres

           (6 rows)

           postgres=# select * from ticket1;

           id

          ——————————————–

          (0 rows)

           測試2:

           在postgres用戶下建立名為test2的schema

           postgres=# create schema test2;

           CREATE SCHEMA

           postgres=# create table test2.ticket2(id int);

           CREATE TABLE

          建立兩個普通用戶

           postgres=# create role test1 login password ‘123’;

           CREATE ROLE

           postgres=# create role test2 login password ‘123’;

           CREATE ROLE

          普通用戶連接數據庫

           postgres=# c postgres test2;

           Password for user test2:

          You are now connected to database “postgres” as user “test2”.

           postgres=> d

           List of relations

           Schema | Name | Type | Owner

          ————————-+———

          public | dept | table | postgres

           public | emp | table | postgres

           public | jobhist | table | postgres

           public | next_empno | sequence | postgres

           public | salesemp | view | postgres

           (5 rows)

          postgres=> show search_path ;

           search_path

          —————-

          “$user”,public

           (1 row)

          postgres=> set search_path to “$user”,public,test1;

           SET

          postgres=> d

           List of relations

           Schema | Name | Type | Owner

          ————————-+———

          public | dept | table | postgres

           public | emp | table | postgres

           public | jobhist | table | postgres

           public | next_empno | sequence | postgres

           public | salesemp | view | postgres

           test1 | ticket1 | table | postgres

           test2 | ticket2 | table | postgres

           (11 rows)

           可以看到test2用戶模式下的ticket2表,但是訪問時權限不足。

           postgres=> select * from test2.ticket2;

           ERROR: permission denied for relation ticket2

           postgres=> select * from ticket2;

          ERROR: permission denied for relation ticket2

           通過postgres超級用戶賦予權限,即可訪問

           postgres=# grant select on all tables in schema test2 to test1;

           GRANT

           postgres=> select * from test2.ticket2;

           id

          —————————————————

          (0 rows)

          postgres=> select * from ticket2;

          id

          —————————————————

          (0 rows)

          方法B:通過dblink實現跨庫訪問

          方法B測試示例如下:

          環境:本地:192.168.56.88 數據庫:postgres

           遠程:192.168.56.99 數據庫:test

           

          PostgreSQL通過dblink實現跨庫訪問

          測試1:在同一個實例下分別建立兩個數據庫,通過dblink 實現跨庫訪問

          postgres=# create database test;

          CREATE DATABASE

          postgres=# l

                                       List of databases

             Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges 

          ———–+———-+———-+———+——-+———————–

           postgres  | postgres | UTF8     | C       | C     |

           template0 | postgres | UTF8     | C       | C     | =c/postgres          +

                     |          |          |         |       | postgres=CTc/postgres

           template1 | postgres | UTF8     | C       | C     | =c/postgres          +

                     |          |          |         |       | postgres=CTc/postgres

           test      | postgres | UTF8     | C       | C     |

          (4 rows)

          postgres=# c test

          You are now connected to database “test” as user “postgres”.

          test=# create table test(id int);

          CREATE TABLE

          test=# d

                  List of relations

           Schema | Name | Type  |  Owner 

          ——–+——+——-+———-

           public | test | table | postgres

          (1 row)

          test=# create table test2(id int);

          CREATE TABLE

          test=# insert into test values (‘1111’);

          INSERT 0 1

          test=# c postgres

          You are now connected to database “postgres” as user “postgres”.

          在postgres數據庫中建立dblink連接到test數據庫

          postgres=# create extension dblink;

          CREATE EXTENSION

          postgres=# select * from pg_extension;

           extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition

          ———+———-+————–+—————-+————+———–+————–

           plpgsql |       10 |           11 | f              | 1.0        |           |

           dblink  |       10 |         2200 | t              | 1.1        |           |

          (2 rows)

          postgres=# select dblink_connect(‘test_dblink’,’dbname=test host=localhost port=5432 user=postgres password=postgres’);

           dblink_connect

          —————-

           OK

          (1 row)

          postgres=# select * from dblink(‘test_dblink’,’select * from test’) as t1(id int);

            id

          ——

           1111

          (1 row)

          通過建立dblink,在postgres數據庫可以很容易的訪問到test數據庫中的數據。

          為了訪問test數據庫中的數據方便,我們可以建立一個視圖,操作如下,我們只需要查詢視圖中的內容即可。

          postgres=# CREATE VIEW testdb_dblink AS 

          postgres-# SELECT * FROM dblink(‘hostaddr=127.0.0.1 port=5432 dbname=test user=postgres password=postgres’, ‘SELECT * From test’) AS t(id int);

          CREATE VIEW

          postgres=# d

                            List of relations

           Schema |          Name           | Type  |  Owner 

          ——–+————————-+——-+———-

           public | ptest1                  | table | postgres

           public | ptest2                  | table | postgres

           public | remote_people_user_name | view  | postgres

           public | testdb_dblink           | view  | postgres

          (4 rows)

          postgres=# select * from testdb_dblink ;

            id

          ——

           1111

          (1 row)

          測試2:

          在兩個實例下分別創建數據庫,然后通過dblink實現垮庫訪問。

          實例1:

          首先需要配置下路由配置,添加一行命令-A INPUT -s 192.168.0.0/16 -j ACCEPT

          [root@darry etc]# vi /etc/sysconfig/iptables

          添加-A INPUT -s 192.168.0.0/16 -j ACCEPT  即允許192.168.0.0的網段訪問

          ….

          [root@darry etc]# service iptables reload

          iptables: Trying to reload firewall rules:                 [  OK  ]

          在IP為192.168.56.88(本地)的postgres數據庫中建立extension

          postgres=# create extension dblink;

          CREATE EXTENSION

          postgres=# select  * from pg_extension;

           extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition

          ———+———-+————–+—————-+————+———–+————–

           plpgsql |       10 |           11 | f              | 1.0        |           |

           dblink  |       10 |         2200 | t              | 1.1        |           |

          (2 rows)

          建立dblink 訪問IP為192.168.56.99(遠程)數據庫

          postgres=# select dblink_connect(‘test_dblink’,’dbname=test host=192.168.56.99 port=5432 user=postgres password=postgres’);

           dblink_connect

          —————-

           OK

          (1 row)

           

          postgres=# select * from dblink(‘test_dblink’,’select * from test’) as t1(id int);

            id

          ——

           1111

          (1 row)

          跨庫事務測試

          連接遠程數據庫

          postgres=# select dblink_connect(‘test_dblink’,’dbname=test host=192.168.56.99 port=5432 user=postgres password=postgres’);

           dblink_connect

          —————-

           OK

          (1 row)

          在遠程服務器上開始一個事務

          postgres=# select dblink_exec(‘test_dblink’,’begin;’);

           dblink_exec

          ————-

           BEGIN

          (1 row)

          插入一條數據

          postgres=# select dblink_exec(‘test_dblink’,’insert into test values(7777);’);

           dblink_exec

          ————-

           INSERT 0 1

          (1 row)

          經查看遠程服務器上已經插入一條數據

          postgres=# select * from dblink(‘test_dblink’,’select * from test’) as t1(id int);

            id 

          ——-

            1111

            2222

            3333

            4444

            6666

           33333

            7777

          (11 rows)

          在遠程數據庫中查看未發現數據,因為事務未提交

          test=# select * from test;

            id 

          ——-

            1111

            2222

            3333

            4444

            6666

           33333

          在本地數據庫中提交遠程連接數據庫中的事務

          postgres=# select dblink_exec(‘test_dblink’,’commit;’);

           dblink_exec

          ————-

           COMMIT

          (1 row)

          再次查看

          postgres=# select * from dblink(‘test_dblink’,’select * from test’) as t1(id int);

            id 

          ——-

            1111

            2222

            3333

            4444

            6666

           33333

            7777

          遠程數據庫中也存在

          test=# select * from test;

            id 

          ——-

            1111

            2222

            3333

            4444

            6666

           33333

            7777

          若換成將commit替換成rollback則插入取消

          postgres=# select dblink_exec(‘test_dblink’,’begin;’);

           dblink_exec

          ————-

           BEGIN

          (1 row)

          postgres=# select dblink_exec(‘test_dblink’,’insert into test values(99999);’);

           dblink_exec

          ————-

           INSERT 0 1

          postgres=# select * from dblink(‘test_dblink’,’select * from test’) as t1(id int);

            id 

          ——-

            1111

            2222

            3333

            4444

            6666

           33333

            7777

           99999

          執行回滾操作

          postgres=# select dblink_exec(‘test_dblink’,’rollback;’);

           dblink_exec

          ————-

           ROLLBACK

          (1 row)

          經查看回滾之后,不記錄之前插入的數據

          postgres=# select * from dblink(‘test_dblink’,’select * from test’) as t1(id int);

             id 

          ——-

            1111

            2222

            3333

            4444

            6666

           33333

            7777

          方法C:通過postgres_fdw實現跨庫訪問

          環境:本地:192.168.0.14,遠程:192.168.0.17,PG:9.3.9兩臺機器的測試用戶及數據庫均為:test,test

          1.在本地數據庫中創建postgres_fdw extension.

          [postgres@minion1 bin]$ ./psql test test

          psql (9.3.9)

          Type “help” for help.

          test=# c test test

          You are now connected to database “test” as user “test”.

          test=# create extension postgres_fdw ;

          CREATE EXTENSION

          2.在遠程數據庫上生成測試數據 :

          [postgres@minion4 bin]$ ./psql test test

          psql (9.3.9)

          Type “help” for help.

          test=# CREATE TYPE user_enum AS ENUM (‘foo’, ‘bar’, ‘buz’);

          CREATE TYPE

          test=# dT

                  List of data types

           Schema |   Name    | Description

          ——–+———–+————-

           public | user_enum |

          (1 row)

           

          test=# select oid from pg_type where typname=’user_enum’;

            oid

          ——-

           16902

          (1 row)

          test=# CREATE SCHEMA test;

          CREATE SCHEMA

          test=# CREATE TABLE test.test1 (

          test(# c1 int NOT NULL,

          test(# c2 int NOT NULL,

          test(# c3 text,

          test(# c4 timestamptz,

          test(# c5 timestamp,

          test(# c6 varchar(10),

          test(# c7 char(10),

          test(# c8 user_enum,

          test(# CONSTRAINT t1_pkey PRIMARY KEY (c1)

          test(# );

          CREATE TABLE

          test=# CREATE TABLE test.test2 (

          test(# c1 int NOT NULL,

          test(# c2 text,

          test(# CONSTRAINT t2_pkey PRIMARY KEY (c1)

          test(# );

          CREATE TABLE

          test=# INSERT INTO test.test1

          test-# SELECT id,

          test-#        id % 10,

          test-#        to_char(id, ‘FM00000’),

          test-#        ‘1970-01-01’::timestamptz + ((id % 100) || ‘ days’)::interval,

          test-#        ‘1970-01-01’::timestamp + ((id % 100) || ‘ days’)::interval,

          test-#        id % 10,

          test-#        id % 10,

          test-#        ‘foo’::user_enum

          test-# FROM generate_series(1, 1000) id;

          INSERT 0 1000

          test=# INSERT INTO test.test2

          test-# SELECT id,

          test-#        ‘AAA’ || to_char(id, ‘FM000’)

          test-# FROM generate_series(1, 100) id;

          INSERT 0 100

          test=# analyze test.test1;

          ANALYZE

          test=# analyze test.test2;

          ANALYZE

          3.在本地數據庫中創建server

          test=# CREATE SERVER s1 FOREIGN DATA WRAPPER postgres_fdw;

          CREATE SERVER

          test=# select * from pg_foreign_server ;

           srvname | srvowner | srvfdw | srvtype | srvversion | srvacl | srvoptions

          ———+———-+——–+———+————+——–+————

           s1      |    17444 |  17449 |         |            |        |

          (1 row)

          test=# alter server s1 options ( add hostaddr ‘192.168.0.17’, add port ‘5432’, add dbname ‘test’);

          ALTER SERVER

          4.SERVER賦權 :

          test=# grant usage on foreign server s1 to test;

          GRANT

          test=# select * from pg_foreign_server ;

           srvname | srvowner | srvfdw | srvtype | srvversion |    srvacl     |                  srvoptions  

                       

          ———+———-+——–+———+————+—————+——————————–

          —————

           s1      |    17444 |  17449 |         |            | {test=U/test} | {hostaddr=192.168.0.17,port=543

          2,dbname=test}

          (1 row)

          5.在本地數據庫中創建user mapping :

          test=# create user mapping for test server s1 options(user ‘test’,password ‘test’);

          CREATE USER MAPPING

          6.在本地數據庫中創建foreign table

          test=# CREATE TYPE user_enum AS ENUM (‘foo’, ‘bar’, ‘buz’);

          CREATE TYPE

          test=# dT

                  List of data types

           Schema |   Name    | Description

          ——–+———–+————-

           public | user_enum |

          (1 row)

           

          test=# select oid from pg_type where typname=’user_enum’;

            oid

          ——-

           17453

          (1 row)

          test=# CREATE FOREIGN TABLE ft1 (

          test(#  c0 int,

          test(#  c1 int NOT NULL,

          test(#  c2 int NOT NULL,

          test(#  c3 text,

          test(#  c4 timestamptz,

          test(#  c5 timestamp,

          test(#  c6 varchar(10),

          test(#  c7 char(10),

          test(#  c8 user_enum

          test(#  ) SERVER s1 options(schema_name ‘test’, table_name ‘test1’);

          CREATE FOREIGN TABLE

          test=# select * from ft1 limit 1;

          ERROR:  column “c0” does not exist

          CONTEXT:  Remote SQL command: SELECT c0, c1, c2, c3, c4, c5, c6, c7, c8 FROM test.test1

          test=# alter foreign table ft1 drop column c0;

          ALTER FOREIGN TABLE

          test=# select * from ft1 limit 1;

           c1 | c2 |  c3   |           c4           |         c5          | c6 |     c7     | c8

          —-+—-+——-+————————+———————+—-+————+—–

            1 |  1 | 00001 | 1970-01-02 00:00:00+08 | 1970-01-02 00:00:00 | 1  | 1          | foo

          (1 row)

          test=# create foreign table ft2 (c2 text,c1 int not null) server s1 options(schema_name ‘test’,table_name ‘test2’);

          CREATE FOREIGN TABLE

          test=# select * from ft2 limit 1;

             c2   | c1

          ——–+—-

           AAA001 |  1

          (1 row)

          test=# create foreign table ft3(c2 text,c3 int not null) server s1 options(schema_name ‘test’,table_name ‘test2’);

          CREATE FOREIGN TABLE

          test=# select * from ft3 limit 1;

          ERROR:  column “c3” does not exist

          CONTEXT:  Remote SQL command: SELECT c2, c3 FROM test.test2

          test=# alter foreign table ft3 alter column c3 options (column_name ‘c1’);

          ALTER FOREIGN TABLE

          test=# select * from ft3 limit 1;

             c2   | c3

          ——–+—-

           AAA001 |  1

          (1 row)

          test=# create foreign table ft4(c2 text,c3 int options (column_name ‘c1’) not null) server s1 options(schema_name ‘test’,table_name ‘test2’);

          CREATE FOREIGN TABLE

          test=# select * from ft4 limit 2;

             c2   | c3

          ——–+—-

           AAA001 |  1

           AAA002 |  2

          (2 rows)

          PostgreSQL跨庫訪問事務測試

          遠程機器創建測試表

          test=# create table test3(id int);

          CREATE TABLE

          test=# select * from test3;

           id

          —-

          (0 rows)

          本地機器測試

          創建對應的外部表

          test=# create foreign table ft_test3(id int) server s1 options(schema_name ‘test’,table_name ‘test3’);

          CREATE FOREIGN TABLE

          test=# select * from ft_test3 ;

           id

          —-

          (0 rows)

          本地機器事務測試(不提交)

          test=# begin;

          BEGIN

          test=# insert into ft_test3 values (100);

          INSERT 0 1

          test=# insert into ft_test3 values (200);

          INSERT 0 1

          test=# insert into ft_test3 values (300);

          INSERT 0 1

          test=# select * from ft_test3 ;

           id

          —–

           100

           200

           300

          (3 rows)

          test=# rollback;

          ROLLBACK

          test=# select * from ft_test3 ;

           id

          —-

          (0 rows)

          本地機器事務測試(提交)

          test=# begin;

          BEGIN

          test=# insert into ft_test3 values (1000);

          INSERT 0 1

          test=# insert into ft_test3 values (2000);

          INSERT 0 1

          test=# insert into ft_test3 values (3000);

          INSERT 0 1

          test=# end;

          COMMIT

          test=# select * from ft_test3 ;

            id

          ——

           1000

           2000

           3000

          (3 rows)

          test=# rollback;

          NOTICE:  there is no transaction in progress

          ROLLBACK

          標簽[db:關鍵字]

          相關下載

          查看所有評論+

          網友評論

          網友
          您的評論需要經過審核才能顯示

          熱門閱覽

          最新排行

          公眾號

          主站蜘蛛池模板: 国产一区二区影院| 国产一区二区三区美女| 欧美亚洲精品一区二区| 日本视频一区在线观看免费| 中文字幕亚洲一区二区三区| 国模吧一区二区三区精品视频 | 国产一区精品视频| 国产精品久久亚洲一区二区| 美女AV一区二区三区| 亚洲福利一区二区精品秒拍| 中文字幕一区二区区免| 国产日韩视频一区| 成人免费区一区二区三区| 东京热人妻无码一区二区av| 日本午夜精品一区二区三区电影| 无码一区二区三区免费| 亚洲日韩AV无码一区二区三区人 | 亚洲国产AV一区二区三区四区| 国产SUV精品一区二区88| 日本强伦姧人妻一区二区| 精品国产香蕉伊思人在线在线亚洲一区二区| 国产精品一区二区av不卡| 亚洲av无一区二区三区| 精品免费久久久久国产一区| 一区二区三区在线观看| 中文字幕日本精品一区二区三区| 中文字幕乱码亚洲精品一区| 一区二区三区国产| 精品视频一区二区| 久久精品无码一区二区三区免费 | 日韩免费无码一区二区视频| 精品视频午夜一区二区| 久久国产一区二区| 亚洲综合av一区二区三区不卡| 免费高清av一区二区三区| 久久精品一区二区三区中文字幕| 亚洲AV无码一区二区三区鸳鸯影院 | 日韩视频一区二区| 日韩免费无码一区二区三区| 奇米精品一区二区三区在| 国产伦精品一区二区三区女|