ORACLE公有/私有同義詞

還不算暈發表於2013-11-03

同義詞概念:

1. 同義詞可以是表、索引、序列、過程、函式、包、檢視、資料鏈等模式物件的一個別名。經常用於簡化物件訪問和提高物件訪問的安全性。在使用同義詞時,Oracle資料庫將它翻譯成對應方案物件的名字。oracle資料庫只在資料字典中儲存其定義描述,同義詞不佔用任何實際的物理空間。
2. 使用同義詞優點:避免當管理員對資料庫物件做出修改和變動之後,必須重新編譯應用程式。使用同義詞後,即使引用的物件發生變化,也只需要在資料庫中對同義詞進行修改,而不對應用程式做任何修改。
3. 同義詞分類:公有同義詞、私有同義詞。公有同義詞由public使用者組擁有,資料庫中的所有使用者都可以使用公有同義詞。公用同義詞往往用來標示一些比較普通的資料庫物件,這些物件往往大家都需要引用。
私有同義詞只被建立它的使用者所擁有,只能由該使用者以及被授權的其他使用者使用。這個同義詞的建立者,可以通過授權控制其他使用者是否有權使用屬於自己的私有同義詞。
################################################################################

同義詞作用:

1) 多使用者協同開發中,可以遮蔽物件的名字及其持有者。如果沒有同義詞,當操作其他使用者的表時,必須通過user名.object名的形式,採用了Oracle同義詞之後就可以隱蔽掉user名,當然這裡要注意的是:public同義詞只是為資料庫物件定義了一個公共的別名,其他使用者能否通過這個別名訪問這個資料庫物件,還要看是否已經為這個使用者授權。
2) 為使用者簡化sql語句。上面的一條其實就是一種簡化sql的體現,同時如果自己建的表的名字很長,可以為這個表建立一個Oracle同義詞來簡化sql開發。
3)為分散式資料庫的遠端物件提供位置透明性。
4)Oracle同義詞在資料庫連結中的作用
資料庫連結是一個命名的物件,說明一個資料庫到另一個資料庫的路徑,通過其可以實現不同資料庫之間的通訊。

Create database link 資料庫鏈名 connect to user名 identified by 口令 using ‘Oracle連線串’; 訪問物件要通過 object名@資料庫鏈名。然後建立同義詞:create synonym table_name for table_name@DB_Link;同義詞在資料庫鏈中的作用就是提供位置透明性。

####################################################################################

與同義詞相關的許可權有CREATE SYNONYM、CREATE ANY SYNONYM、CREATE PUBLIC SYNONYM許可權。
本文實驗主要是針對表建立的同義詞。關於針對函式建立同義詞,http://blog.csdn.net/q947817003/article/details/14103801  博文的第5小節有應用。

1:建立同義詞所需許可權管理

使用者在自己的模式下建立私有同義詞,這個使用者必須擁有CREATE SYNONYM許可權,否則不能建立私有同義詞。報錯:ORA-01031: insufficient privileges

如需建立公有同義詞,則需要相應的create public synonym許可權

已經授予CONNECT、RESOURCE的普通使用者預設不具有建立私有、公有同義詞的許可權;需要授權。

DBA使用者有建立公有/私有同義詞許可權。
用sys或DBA賬號給SCOTT賬號賦予CREATE SYNONYM及create public synonym許可權
BYS@bys1>grant create synonym to scott;
Grant succeeded.
BYS@bys1>grant create public synonym to scott;
Grant succeeded.
建立公有同義詞
SCOTT@bys1>create public synonym test1 for dept;
Synonym created.
建立私有同義詞
SCOTT@bys1>create synonym test for dept;
Synonym created.

2:如果需要在其它模式下建立同義詞,則必須具有CREATE ANY SYNONYM的許可權。

用sys或DBA賬號給TEST賬號賦予CREATE ANY SYNONYM的許可權,沒有create any public synonym許可權。
BYS@bys1>grant create any synonym to test;
Grant succeeded.
BYS@bys1>conn test/test;
Connected.
TEST@bys1>create  synonym test1 for scott.dept;
Synonym created.

3:建立同義詞示例

普通用法如下所示:
CREATE [OR REPLACE] [PUBLIC] SYNONYM [ schema.] 同義詞名稱 FOR [ schema.] object [ @dblink ];

--建立私有同義詞-需要CREATE SYNONYM許可權
SCOTT@bys1>create synonym test for dept;

--建立公有同義詞則需要CREATE PUBLIC SYNONYM許可權
SCOTT@bys1>create public synonym test1 for dept;
Synonym created.

如果要建立一個遠端的資料庫上的某張表的同義詞,需要先建立一個Database Link(資料庫連線)來擴充套件訪問,然後再使用如下語句建立資料庫同義詞:
create synonym table_name for table_name@DB_Link;

公共同義詞是和使用者的schema無關的,但是公共的意思並不是所有的使用者都可以訪問它,必須被授權後才能進行;私有同義詞是schema的物件
注意:如果使用者要使用該同義詞,必須具有訪問同義詞對應的物件的許可權。不然報錯:表或檢視不存在。

4.檢視同義詞

使用DBA使用者從DBA_SYNONYMS檢視中檢視指定名字的同義詞及其所屬使用者、物件。
BYS@bys1>col owner for a10
BYS@bys1>SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME like 'TEST%';
OWNER      SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME DB_LINK
---------- ------------------------------ ------------------------------ ---------- ----------
PUBLIC     TEST                           BYS                            DEPT
PUBLIC     TEST1                          SCOTT                          DEPT
BYS        TEST                           BYS                            DEPT
TEST       TEST1                          SCOTT                          DEPT
檢視當前使用者下的同義詞
col table_name for a10
col db_link for a10
TEST@bys1>SELECT * FROM USER_SYNONYMS;
SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME DB_LINK
------------------------------ ------------------------------ ---------- ----------
TEST1                          SCOTT                          DEPT

5.使用同義詞--就像使用表名一樣簡單

存在同名物件和同義詞時,資料庫優先選擇物件作為目標;存在同名私有物件和公共物件時,資料庫優先選擇私有同義詞作為目標

同一使用者下,物件和私有同義詞不能同名。物件可以和公有同義詞同名;私有同義詞也可以和公有同義詞同名;但是同一使用者下,物件和私有同義詞不能同名
即使用時的優先順序:

同名物件>>>同名公有同義詞

同名私有同義詞>>>同名公有同義詞
當使用一個沒有指定schema的同義詞是,首先在使用者自己的schema中尋找,然後再公共同義詞中尋找。
同時要注意:
TEST@bys1>create  synonym test1 for scott.dept;這語句建立同義詞後,如果使用者要使用該同義詞,必須具有訪問scott.emp表的許可權。不然報錯:表或檢視不存在。
TEST@bys1>select * from test1;
select * from test1
              *
ERROR at line 1:
ORA-00942: table or view does not exist
TEST@bys1>conn scott/tiger
Connected.
SCOTT@bys1>grant select on dept to test;
Grant succeeded.
SCOTT@bys1>conn test/test
Connected.
TEST@bys1>select * from test1;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
#######################################
使用同義詞進行查詢示例:--以下四句顯示結果都是DEPT表的內容,節約篇幅,未將查詢一一貼出。
BYS@bys1>select * from test;     
BYS@bys1>select * from test1;
BYS@bys1>select * from test.test1;
BYS@bys1>select * from bys.test;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

6.刪除同義詞

刪除同義詞語法:DROP [ PUBLIC ] SYNONYM [ schema. ] 同義詞名稱 [ FORCE ];

刪除私有同義詞

BYS@bys1>SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME like 'TEST%';
OWNER      SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME DB_LINK
---------- ------------------------------ ------------------------------ ---------- ----------
PUBLIC     TEST                           BYS                            DEPT
PUBLIC     TEST1                          SCOTT                          DEPT
BYS        TEST                           BYS                            DEPT
TEST       TEST1                          SCOTT                          DEPT
BYS@bys1>select * from cat;
TABLE_NAME TABLE_TYPE
---------- -----------
DEPT       TABLE
EMP        TABLE
SEQ1       SEQUENCE
SYS_TEMP_F TABLE
BT
TEST       SYNONYM
BYS@bys1>drop synonym test;   不加PUBLIC關鍵字時,預設刪除的是私有同義詞。並且刪除同義詞後,同義詞所對應的物件不受影響。
Synonym dropped.
BYS@bys1>select * from cat;
TABLE_NAME TABLE_TYPE
---------- -----------
DEPT       TABLE
EMP        TABLE
SEQ1       SEQUENCE
SYS_TEMP_F TABLE
BT
BYS@bys1>SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME like 'TEST%';
OWNER      SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME DB_LINK
---------- ------------------------------ ------------------------------ ---------- ----------
PUBLIC     TEST                           BYS                            DEPT
PUBLIC     TEST1                          SCOTT                          DEPT
TEST       TEST1                          SCOTT                          DEPT

刪除公有同義詞

BYS@bys1>drop public synonym test1;     指定public關鍵字刪除公有同義詞,同義詞所對應的物件不受影響。
Synonym dropped.
BYS@bys1>SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME like 'TEST%';
OWNER      SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME DB_LINK
---------- ------------------------------ ------------------------------ ---------- ----------
PUBLIC     TEST                           BYS                            DEPT
TEST       TEST1                          SCOTT                          DEPT
BYS@bys1>select * from cat;
TABLE_NAME TABLE_TYPE
---------- -----------
DEPT       TABLE
EMP        TABLE
SEQ1       SEQUENCE
SYS_TEMP_F TABLE
BT

7.編譯同義詞

當同義詞的原物件被重新建立時,同義詞需要重新編譯--此編譯操作需要SYSDBA許可權,DBA使用者執行報錯。

BYS@bys1>alter synonym test.test1 compile;
alter synonym test.test1 compile
*
ERROR at line 1:
ORA-01031: insufficient privileges
BYS@bys1>conn / as sysdba
Connected.
SYS@bys1>alter synonym test.test1 compile;
Synonym altered.

對原物件進行DDL操作後,同義詞的狀態會變成INVALID;當再次引用這個同義詞時,同義詞會自動編譯,狀態會變成VALID,無需人工干預,當然前提是不改變原物件的名稱

BYS@bys1>create synonym test for dept;
Synonym created.
BYS@bys1>select object_name,object_type,status from user_objects where object_name='DEPT' or object_name='TEST';
OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
DEPT                 TABLE               VALID
TEST                 SYNONYM             VALID
BYS@bys1>select object_name,object_type,status from user_objects where object_name='DEPT' or object_name='TEST';
OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
DEPT                 TABLE               VALID
TEST                 SYNONYM             VALID

BYS@bys1>drop table dept;   刪除同義詞對應的物件
Table dropped.

BYS@bys1>select object_name,object_type,status from user_objects where object_name='DEPT' or object_name='TEST';
OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
TEST                 SYNONYM             INVALID     -----此時同義詞的狀態已經為INVALID

BYS@bys1>select * from test;     此時查詢同義詞時會報錯:同義詞的狀態不是有效的。
select * from test
              *
ERROR at line 1:
ORA-00980: synonym translation is no longer valid

BYS@bys1>flashback table dept to before drop;
Flashback complete.
閃回刪除的表後,檢視物件狀態,表已經是VALID,同義詞仍是INVALID。
BYS@bys1>select object_name,object_type,status from user_objects where object_name='DEPT' or object_name='TEST';
OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
DEPT                 TABLE               VALID
TEST                 SYNONYM             INVALID

BYS@bys1>select * from test;
    DEPTNO DNAME          LOC
---------- -------------- --------------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
此時使用同義詞進行一次查詢後,同義詞狀態自動變為可用。
BYS@bys1>select object_name,object_type,status from user_objects where object_name='DEPT' or object_name='TEST';
OBJECT_NAME          OBJECT_TYPE         STATUS
-------------------- ------------------- -------
DEPT                 TABLE               VALID
TEST                 SYNONYM             VALID

8.實驗證明如果有查詢某表許可權,可以直接使用其它使用者下私有同義詞

在test5使用者下建立私有同義詞,私有同義詞查詢bys.dept表。 test6使用者有查詢bys.dept表許可權。 test6使用者可以直接查詢test5使用者私有同義詞test5.depta。。
BYS@ bys3>create user test5 identified by test1;
User created.
BYS@ bys3>grant connect,resource to test5;
Grant succeeded.
BYS@ bys3>create user test6 identified by test1;
User created.
BYS@ bys3>grant connect,resource to test6;
Grant succeeded.
BYS@ bys3>conn test5/test1
Connected.
TEST5@ bys3>create sysnonym depta for bys.emp;
create sysnonym depta for bys.emp
       *
ERROR at line 1:
ORA-00901: invalid CREATE command
授權建立同義詞許可權:
TEST5@ bys3>conn bys/bys
Connected.
BYS@ bys3>grant create synonym to test5;
Grant succeeded.

BYS@ bys3>grant create synonym to test6;
Grant succeeded.
BYS@ bys3>grant select on dept to test5;
Grant succeeded.
BYS@ bys3>grant select on dept to test6;
Grant succeeded.
BYS@ bys3>conn test5/test1
Connected.
TEST5@ bys3>create synonym depta for bys.dept;
Synonym created.
TEST5@ bys3>select * from depta;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        40 OPERATIONS     BOSTON
        99 chedan         bj

TEST5@ bys3>conn test6/test1
Connected.
TEST6@ bys3>select * from depta;
select * from depta
              *
ERROR at line 1:
ORA-00942: table or view does not exist

TEST6@ bys3>select * from test5.depta;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        40 OPERATIONS     BOSTON
        99 chedan         bj


常見問題三例:

1:公用同義詞與私有同義詞能否同名呢?如果可以,訪問同義詞時,是共有同義詞還是私有同義詞優先?
可以,如果存在公用同義詞和私有同義詞同名的情況,在訪問同義詞是,訪問的是私有同義詞的指向的物件。

2:為什麼OE使用者建立的公用同義詞,HR使用者不能訪問呢?
因為HR沒有訪問OE模式下物件的許可權,如果OE模式給HR使用者賦予了SELECT物件等許可權,那麼HR使用者即可訪問。

3:物件、私有同義詞、公共同義詞是否可以存在三者同名的情況?
注意:物件(表)與私有同義詞不能同名,否則會報ORA-00955錯誤
建立公共同義詞TEST,如下所示,公共同義詞可以和物件也可以和私有同義詞同名。
結論:
存在同名物件和公共同義詞時,資料庫優先選擇物件作為目標。
存在同名私有物件和公共物件時,資料庫優先選擇私有同義詞作為目標

相關文章