链接到远程数据库
在一个分布式的环境里,数据库链接是定义到其它数据库的路径的一个重要方法,使得远程处理天衣无缝。
要获得数据库链接的更深奥的知识,查看Oracle8i SQL Reference(Oracle8i SQL参考)和Oracle8i Concepts (Oracle8i概念手册)。详细资料的另一个极好的来源是Oracle8i Distributed Database Systems(Oracle8i分布式数据库系统手册)。
今天许多运行Oracle的机构有不止一个Oracle数据库。有时不管原计划是否这样,一个数据库中的数据可能与另一数据库中的数据关联。出现这种情况时,你可以链接这两个数据库使得用户或应用程序可以访问所有数据,就好象它们在一个数据库中。当你这么做时,你就有了一个分布式数据库系统。
如何将两个数据库链接在一起呢?使用一个数据库链接来完成。数据库链接是定义一个数据库到另一个数据库的路径的对象。数据库链接允许你查询远程表及执行远程程序。在任何分布式环境里,数据库链接都是必要的。
简单案例
数据库链接的目的是定义一条到远程数据库的路径,使你可以通过在本地执行一条SQL语句来使用那个数据库中的表和其它的对象。例如,你在一个远程数据库上有一个称之为"geographic feature name"的表,而你想在已连接到你本地数据库的情况下访问那些数据。数据库链接正是你所需要的。在建立它之前,你必须搜集如下信息:
一个网络服务名称,你的本地数据库事例能够使用它来与远程事例相连接远程数据库上的有效用户名和口令网络服务名称是每一个数据库链接必需的。每一次你从客户机PC使用SQL*Plus连接到你的数据库时都要使用服务名称。在那些情况下,你提供给SQL*Plus的网络服务名称是通过在你的客户机上的nsnames.ora文件中查找它们来解析的。在数据库链接中使用的网络服务名称也是如此,除非是那些名字是使用驻留在服务器上的tnsnames.ora文件来解析。
在你定义数据库链接时指定的用户名和口令,用于建立与远程事例的连接。不需硬编码用户名和口令,建立数据库链接也是可能的甚至是值得选取的。既然这样,现在我们注意这个最直接的例子。
下列语句建立了一个数据库链接,它允许访问客户帐户,这个帐户是事先在GNIS数据库建好的:
CREATE DATABASE LINK GNIS
CONNECT TO GUEST IDENTIFIED BY WELCOME
USING 'GNIS';
链接名称GNIS紧随LINK关键字。当连接到远程事例时,CONNECT TO...IDENTIFIED子句指定UEST/WELCOME作为用户名和口令使用 。USING子句指定通过网络服务名称GNIS建立连接。使用这一链接,现在你可以在远程数据库上查询数据。例如:
SQL> SELECT GFN_FEATURE_NAME
2 FROM GNIS.FEATURE_NAMES@GNIS
3 WHERE GFN_FEATURE_TYPE='falls'
4 AND GFN_STATE_ABBR='MI'
5 AND GFN_COUNTY_NAME='Alger';
GFN_FEATURE_NAME
_________________
Alger Falls
Au Train Falls
Chapel Falls
Miners Falls
Mosquito Falls
Tannery Falls
..
在SELECT语句中@GNIS紧随表名称,说明GNIS.FEATURE_NAMES表是在远程数据库,应该通过GNIS链接访问,链接类型Oracle支持几种不同类型的链接。这些类型相互重叠,有时难以通过选项进行分类。当你建立数据库链接时,你需要从下面选取:
Public(公用)或Private (私有)链接
权限类: Fixed User(固定用户), Connected User(连接用户)或 Current User(当前用户)
Shared Link(共享链接)或 Not Shared Link(非共享链接)
每次创建数据库链接时,你要自觉不自觉地做这三种选择。
公用链接与私有链接相对比
公用数据库链接对所有的数据库用户开放访问权。前面显示的是私有数据库链接,它只对建立它的用户授权。公用数据库链接更为有用,因为它使你不必为每一个潜在用户创建单独的链接。为了建立一个公用数据库链接,使用如下显示的PUBLIC关键字:
CREATE PUBLIC DATABASE LINK GNIS
CONNECT TO GUEST IDENTIFIED BY WELCOME
USING 'GNIS';
即使这是一个公用链接,用户名仍旧固定。所有使用这个链接的用户都作为用户GUEST连接到远程数据库。
使用数据库链接访问远程表
图1 数据库链接GNIS,指明网络服务名称,链接PROD事例到GNIS事例中的FEATURE_NAMES表。
权限类
当你建立一个数据库链接时,关于你如何授权对远程数据库进行访问,有三种选择。这三种选择代表了数据库链接的另一种分类方法。这三种类别如下:
固定用户。为远程数据库链接指定用户名和口令,作为数据库链接定义的一部分。
连接用户。在不指定用户名和口令时创建的数据库链接。
当前用户。建立数据库链接并指定CURRENT_USER关键字。
固定用户数据库链接是指在创建链接时为远程数据库指定用户名和口令。这一链接不管什么时候使用,也无论谁使用,都使用相同的用户名和口令登陆到远程数据库。到目前为止你在本文中所看到的都是固定用户链接。
固定用户链接,尤其是公用固定用户链接的一个潜在问提是他们把远程系统上的同一帐户给了许多本地用户。从安全角度来说,如果所有的本地用户在远程系统上拥有同一个帐户,责任就要折中,这取决于用户的数量 。如果数据丢失,几乎不可能确定破坏是如何发生的。另一个潜在问题是公用固定用户链接将对远程数据库的访问权给了所有的本地数据库用户。
如果你不想在数据库链接中嵌入用户名和口令,Oracle提供给你另一个非常有用的选择。你可以建立一个连接用户链接。连接用户链接是这样的链接,它通过任一个正在使用该链接的本地数据库的用户的用户名和口令登陆到远程数据库。你可以通过简单地空出用户名和口令来建立一个连接用户链接。考虑如下定义:
CREATE PUBLIC DATABASE LINK GNIS
USING 'GNIS';
链接名是GNIS。它连接到远程数据库连接时使用的网络服务名称是GNIS,但是没有指定用户名和口令。当你在查询中使用这个链接时,它将向远程数据库发送你当前的用户名和口令。例如,如果你使用AHMAD/SECRET 登陆到你的本地数据库,那么AHMAD/SECRET将是你登陆到远程数据库时使用的用户名和口令。
为了使用一个连接用户链接,你必须在远程数据库上有一个帐号,了解这一点是很重要的。不但这样,而且你在两个数据库上应使用同样的用户和口令。如果本地登陆使用AHMAD/SECRET,那么登陆到远程数据库时也必须使用同样的用户名和口令。使用连接用户链接时,如果你的口令不同,你就无权登陆。
公用连接用户数据库链接尤其有用,因为你可以建立一个可被所有用户访问的链接,并且所有用户被分别使用他或她自己的用户名和口令授权。你获得责任方面的利益,没有将远程数据库向你的本地数据库上的每一位用户开放。代价是你必须在两个数据库上建立用户帐户,并且你必需确信口令保持一致。
当前用户链接通过使用CURRENT_USER关键字建立并且与连接用户链接相似。只有当使用Oracle Advanced Security Option(Oracle高级安全选项)时,你才能使用当前用户链接,这个链接只对授权使用X.509认证的用户有用。
共享链接
共享数据库链接是指该链接的多个用户可以共享同一个底层网络连接。例如,在有四位用户的MTS(多线程服务器)环境下,每一个共享服务器进程都将与远程服务器有一个物理链接,这四位用户共享这两个链接。
表面上,共享链接乍一听起来像是一件好事。在某些环境下的确如此,但是,当你考虑使用共享链接时,应当意识到这有许多局限性和警告:
如果你使用一个专用的服务器连接来连接到你的本地数据库,链接只能在你从那些连接中创建的多重会话间共享。 在MTS环境里,每一个共享服务器进程潜在地打开一个链接。所有的会话被同一共享服务器进程提供并且分享被那个进程打开的任意共享链接。因为在MTS环境里的一个共享服务器进程能够服务于许多用户连接,共享链接的使用可能导致打开的链接远多于所必须的链接。用SHARED关键字建立共享数据库链接。还必须使用AUTHENTICATED BY 子句在远程系统上指定一有效的用户名和口令。如下命令建立一个共享的、公用的、连接用户数据库链接:
CREATE SHARED PUBLIC DATABASE LINK GNIS
AUTHENTICATED BY DUMMY_USER IDENTIFIED BY SECRET
USING 'GNIS';
要获得创建链接和管理分布式系统的更多资料,请查阅Oracle Technology Network (http://otn.oracle.com/)。
使用AUTHENTICATED BY子句稍微有些困扰,但是由于实现共享链接的方式安全性决定它是必须的。这个例子中的用户名和口令DUMMY_USER/SECRET必须在远程系统上有效。然而,远程系统上使用的帐户仍就是连接用户的帐户。如果我以JEFF/SECRET登陆到我的本地数据库并使用我刚建好的共享链接,将会发生以下一系列事件:
为了打开链接,Oracle使用DUMMY_USER/SECRET向远程数据库授权。 然后,Oracle试图使用HMAD/SECRET使我登陆到远程数据库。共享链接的主要目的是减少两个数据库服务器之间的底层网络连接数量。它们最适合于MTS环境,在那你拥有大量的通过这一链接访问远程数据库的用户。观念上,你想让用户数量超过共享服务器进程的数量。那么你可以通过为每一共享服务器进程打开一个链接而不是每位用户打开一个链接的方法,节省资源。
查找关于数据库链接的资料
你可以从几个数据字典视图中获得建立好的数据库链接的资料。DBA_DB_LINKS视图为每一定义的链接返回一行。OWNER 列和DB_LINK列分别显示了这一链接的所有者及名称。对公用数据库链接,OWNER列将包含'PUBLIC'。如果你建立固定用户链接,用户名应在DBA_DB_LINKS视图的USERNAME列里,但是口令只能从SYS.LINK$视图中看到。默认情况下,只有具有SELECT ANY TABLE系统权限的DBA能够访问SYS.LINK$视图查看口令。你应该保护访问那个视图的权限。ALL_DB_LINKS 视图和 USER_DB_LINKS视图与 DBA_DB_LINKS视图相类似-它们分别显示了你能够访问的所有链接及你所拥有的全部链接。最后,V$DBLINK动态性能视图向你显示出任意给定时间你-当前用户,打开的全部数据库链接。
全局性的数据库名称
在分布式环境里,Oracle建议你的数据库链接名应与它们连接到的数据库的全局性名称相匹配。因此如果你正在连接到名称为GNIS.GENNICK.ORG的数据库,你应当将你的数据库链接命名为GNIS.GENNICK.ORG
为确定数据库的全局性名称,以SYSTEM登陆并查询GLOBAL_NAME视图:
SQL> SELECT * FROM GLOBAL_NAME;
GLOBAL_NAME
_______________
GNIS.GENNICK.ORG
由于历史的原因,默认情况下,全局性名称与数据库链接名称的之间的链接不是强制性的。不过,你可以通过设置GLOBAL_NAMES的初始化参数为TRUE来改变这一行为。例如:
SQL> SHOW PARAMETER GLOBAL_NAMES
NAME TYPE VALUE
________________________________________________________
global_names boolean TRUE
用于产生这个范例的事例要求你使用的数据库链接名,必须与目标数据库的全局性数据库名称相匹配。注意与一些Oracle文档中说的相反,关键是你的本地事例的GLOBAL_NAMES设置。如果你的本地事例中GLOBAL_NAMES=FALSE,你就能够使用数据库链接,而不用管它们是否与远程数据库的全局性名称相匹配。总的来说,如果你设置GLOBAL_NAMES=TRUE,你应该在你的所有事例中一律这么做。