物件、同義詞和公有同義詞順序選取

realkid4發表於2011-02-22

 

筆者開發的專案中,廣泛使用公有同義詞技術。透過公有同義詞,消除不同資料來源物件之間訪問的差異,做到資料邏輯和物理上的分佈。

 

突然想到一個問題:在一個schema下,如果存在自身物件、私有同義詞和公有同義詞相同,那麼在訪問的時候,Oracle會如何選擇呢?

 

 

一個簡單的實驗,可以告訴我們答案。

 

構建實驗環境

 

思路是在一個使用者下建立三個資料表test、test1、test2。為test1建立私有同義詞private synonym,名稱為test。為test2建立公有同義詞public synonym,名稱為test。

 

SQL> conn scott/tiger@orcl;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as scott

//test建立

SQL> create table test

  2  ( dest varchar2(20));

 

Table created

 

SQL> insert into test values ('I''m test table !');

 

1 row inserted

 

SQL> commit;

 

Commit complete

//test2建立

SQL> create table test2 (dest varchar2(20));

 

Table created

 

SQL> insert into test2 values ('I''m test2 table !');

 

1 row inserted

 

SQL> commit;

 

Commit complete

//test3建立

SQL> create table test3 (dest varchar2(20));

 

Table created

 

SQL> insert into test3 values ('I''m test3 table !');

 

1 row inserted

 

SQL> commit;

 

Commit complete

 

 

 

建立私有和公有同義詞。

 

 

SQL> create synonym test for scott.test2;

 

create synonym test for scott.test2

 

ORA-00955: 名稱已由現有物件使用 //報錯,作為scott使用者私有物件,看來不允許是同名出現!!!

 

//公有同義詞就可以了!

SQL> create public synonym test for scott.test2;

 

Synonym created

 

 

從這裡,我們已經可以獲得一個知識。Oracle是不允許一個owner下面存在相同名稱資料表,但是公共同義詞同名是允許的。那麼,在自身物件和公共同義詞上,Oracle如何選取呢?

 

優先順序選擇實驗A

 

//發出查詢語句

SQL> select * from test;

 

DEST

--------------------

I'm test table !         //訪問的是scott自身下面的資料表test

 

 

SQL> select * from public.test;  //公共同義詞基本不能訪問到。

 

select * from public.test

 

ORA-00903: 表名無效

 

//如果切換了使用者,我們實驗一下。

SQL> conn sys/Conan2002@orcl as sysdba;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as SYS

 

SQL> select * from test;  //公共同義詞起效果。

 

DEST

--------------------

I'm test2 table !

 

 

 

結論:schema裡,當面臨著自身私有物件和公共同義詞物件的時候,Oracle會優先選擇私有物件作為目標

 

如果我們刪除了私有物件呢?繼續實驗。

 

 

SQL> drop table test;

 

Table dropped  //刪除了物件!

 

SQL> select * from test;

 

DEST

--------------------

I'm test2 table !   //刪除了物件,公共同義詞起效果了。

 

 

結論:當存在同名物件的時候,只有在私有物件被去除之後,才可能有訪問到公共同義詞的機會。

 

繼續思考,那麼私有同義詞和公共同義詞之間同名發生時,Oracle做什麼樣的選擇呢?

 

優先順序選擇實驗B

 

資料表test已經被刪除,設定test3表為scott使用者的私有同義詞。

 

 

SQL> create synonym test for scott.test3; //建立私有同義詞

 

Synonym created

 

//優先選擇私有同義詞物件。

SQL> select * from test;

 

DEST

--------------------

I'm test3 table !

 

 

結論顯而易見:在有私有同義詞和公有同義詞的相同的情況下,Oracle優先選擇私有同義詞物件。當然,如果刪除了私有同義詞,公有同義詞也就開始起效果了。

 

 

SQL> drop synonym test;

 

Synonym dropped

 

SQL> select * from test;

 

DEST

--------------------

I'm test2 table !

 

 

 

一個簡單的問題,告訴我們Oracle一個選擇的原則:在選擇物件的時候,範圍是從小而大,可能範圍越小,Oracle認為Schema的可控能力就越強吧。

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-687732/,如需轉載,請註明出處,否則將追究法律責任。

相關文章