一、介绍
Postgresql数据库提供了一个dblink扩展的插件,能够直接在一个数据库中操作另外一个远程数据库,比如:一个数据库在服务器A上,另外一个数据库在服务器B上,我可以在A这台服务器数据库上面建立一个到B服务器数据库的dblink,然后就可以在A服务器上对B服务器的数据库进行query或者update或者delete操作,同理也可以在B服务器数据库上建立一个到A服务器数据库的dblink。因此通过扩展dblink,就可以关联多个数据库进行连表查询了。
二、使用方法
dblink插件是PostgreSQL安装包自带的,如果安装数据库时没有安装dblink,可以重新编译安装。但是pg数据库不会默认扩展dblink,如果要在某个数据库中使用该功能,需要重新扩展dblink才可以,否则会报错不存在错误,如下图所示。
1、扩展dblink
在指定数据库中执行语句:create extension if not exists dblink 即可扩展dblink插件,执行完,如果使用DBeaver工具可以在扩展一栏中看到dblink,如下图所示。
或者执行select * from pg_available_extensions语句查看当前数据库所有已经扩展过的插件,若结果中存在dblink即表示扩展成功。
2、使用dblink
(1)dblink_connect/dblink_connect_u:创建dblink连接
两者用法相似,都表示打开一个到数据库的持久连接,但是dblink_connect需要使用超级用户postgres,而dblink_connect_u不需要,所以不安全,一般不推荐使用。
该函数的使用语法:select dblink_connect('conname','connstr'),它有2个参数conname和connstr,其中conname是可选参数。
① conname:用于这个连接的名字。如果忽略,将打开一个未命名的连接并且替换掉任何现有的未命名连接(一般不推荐忽略)
② connstr:数据库连接信息,格式为:
host=数据库连接ip
port=数据库连接端口
dbname=要连接的数据库名称
user=要连接的数据库用户名
password=要连接的数据库密码
如上图所示,使用DBeaver工具,创建一个dblink,执行sql语句后,如果创建成功会展示OK。上图语句中表示创建了一个名为test的数据库连接,连接到的是10.194.98.82服务器上的xres_xresdb数据库。
(2)dblink_get_connections:查询所有已连接的dblink
改函数的使用语法是:select dblink_get_connections(),它会展示目前数据库中所有已经建立的持久连接
如上图所示,执行语句后,会展示前面已经创建的名称为“test”持久连接。
(3)dblink_disconnect:断开连接
该函数的使用语法是:select dblink_disconnect('conname'),它有一个参数conname:表示需要断开的连接名称,如果该参数忽略表示关闭一个未命名的连接。
执行关闭sql后,如果关闭成功会返回OK,此时再次执行dblink_get_connections查看所有连接,发现为空,表示刚才创建的test连接已经被关闭。
(4)dblink:在一个远程数据库中执行一个操作
这里说的“操作”可以是像操作本地数据库一样进行增删改查,但是日常业务中使用查询操作是最多的。该函数的语法是:
dblink('conname','connstr','sql','fail_on_error'),它包含四个参数:
- conname:要使用的连接名。忽略这个参数将使用未命名连接
- connstr:数据库连接信息,参考语法(1)中的同名字段
- sql:在远程数据库中执行的SQL语句
- fail_on_error:如果为真(忽略是的默认值),那么在连接的远端抛出一个错误时也会在本地抛出一个错误,如果为假,远程错误只在本地被报告未一个NOTICE,并且该函数不返回行
dblink使用的时候有两种方式:第一种已经创建了一个持久连接,第二种没有创建持久连接。
在第一种情况下已经创建命名的连接后,可以直接使用连接名+SQL语句实现,如下所示,但是这种方式的前提是已经提前创建了已命名的持久连接。
第二种情况下,并未创建持久连接时,可以直接通过连接信息+SQL语句的方式实现。
三、总结
Dblink插件它创建了一个通道,使得我们访问远程数据库就像访问本地数据库一样方便。在某些单纯的数据展示的项目中,当用了多个数据库时,如果使用程序取值处理,这样开发性能和效率都不是很好,而用扩展Dblink就非常简单。但是使用dblink的时候注意慎用insert/update/delete等语句,这些操作建议还是回到原始数据库中进行。