鏈接到遠程數據庫
在一個分布式的環境里,數據庫鏈接是定義到其它數據庫的路徑的一個重要方法,使得遠程處理天衣無縫。
要獲得數據庫鏈接的更深奧的知識,查看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,你應該在你的所有事例中一律這么做。