同義詞和屬主問題

      工作中遇到一個數據庫的問題,有關同義詞和屬主的,由於自己對這塊知識不瞭解,所以整理了一下,理了理思路~


      先說明一下,同義詞這個東西,在Oracle中,SqlServer2005以上中有,mysql數據庫中沒有。屬主在這三個數據庫中是都有的。不過工作中遇到的問題是Oracle10的,所以下面的以Oracle爲基礎。


      爲了搞明白這問題,我們先來了解幾個概念:

      1、屬主(owner)用簡單的話來說就是數據庫的用戶。

      2、Schema是數據庫對象的集合,一個用戶一般對應一個schema,該用戶的schema名等於用戶名,並作爲該用戶的缺省schema,這也是爲什麼程序中的schema名都爲數據庫用戶名的原因。注意:Oracle數據庫中不能新創建一個schema,要想創建一個schema,只能通過創建一個用戶的方法解決。

      3、同義詞(synonyms)從字面上理解就是別名的意思,和試圖的功能類似,就是一種映射關係。設置同義詞後,用有權限的用戶訪問時,可以隱蔽掉user名。

 

搞明白了這些概念,我們來看一下它們的一些簡單應用場景:

1、schema的使用

      user是控制權限的,而schema則是一個容器,非所有者如果需要訪問這個容器下的對象,就需要在對象前面寫上schema(owner)的名字。

(1)例如:在同一個庫的實例裏,A、B都有查詢權限,從A用戶下查詢B用的表,就是:select * from B.表名。

 

(2)例如:hibernate在實現實體映射時,DB無需強行指定。部署時會較對DB戶名和密碼,根據用戶名以訪問的表完成實體映射。如果一個帳號可以訪問一個數據庫的下多個表,以oracle爲例用戶user1下面有表table1 ,user2下面也有table1,且user1有user2的所有權限,那麼部署時可能就會搞錯table,出於安全hiberante在配置時設置默認的schema較爲安全。

 

1、同義詞的使用

(1)創建同義詞

 

create public synonym table_name for user.table_name;

 

public:公共的,不加public修飾詞是私有的,公共的名字可以與表名相同,私有的同義詞不可以。

 

public同義詞只是爲數據庫對象定義了一個公共的別名,其他用戶能否通過這個別名訪問數據庫對象,還要看是否已經爲這個用戶授權。

 

你可能需要在user用戶中給當前用戶(user2)授權: grant select/delete/update on 表 to user2。

 

(2)刪除同義詞

       

drop public synonym table_name;


 

(3)查看所有同義詞

           

select * from dba_synonyms;


 

          上面瞭解後,分析下工作中遇到的問題:

      有一個項目X從1.0升級到2.0,需要部署,目前環境是在一個數據庫實例下有A、B、C三個用戶,它們的權限一致,A用戶下面的表是項目X的1.0版本的表,B用戶下面是下面X的2.0的表,A用戶的所有表都設置了公共的同義詞,爲了安全考慮,C用戶是實際對項目X開放的用戶。

      由之前的知識鋪墊可知,在同義詞與表名一致的前提下,如果使用C用戶之間查詢表名,會首先通過公共的同義詞訪問到A用戶下得表,如果再創建一個用戶D,把A的同義詞改爲私有的同義詞,並且只對D授權,D是訪問項目X的1.0的開放用戶,C作爲項目X的2.0的開放用戶,這個方法是可以的,但是有個問題是私有的同義詞名稱不能與表名相同,客戶是想同義詞名與表名保持一致的,便於管理和訪問,所以這個方法不能使用。因此,現在的思路是打算在屬主方面下手來解決問題,對錶制定屬主,這樣一來就不會訪問到公共的同義詞了。

      對於程序的改動:

         在程序的hibernate的properties配置文件中,加入如下配置,指定默認屬主

 

hibernate.default_schema=harold

      注意:程序中,與數據庫相關的sql需要用hql,如果sql語句用createSQLQuery等方法的地方,需要注意會報錯,找不到表,因爲這裏不會走hibernate配置的默認schema。所以這種地方,可以修改爲hql的語句,或者通過程序加載schema。

例如:

 

/**
 加載schema的工具類
 @author harold
 */
public class InitUtil {
	
	/**
	 hibernate的properties文件的文件名
	 */
	private static final String propFileName = "hibernate.properties";
	private static Properties props= new Properties();
	
	/**
	 功能:取得properties配置文件
	 @author harold
	 @return
	 */
	public static Properties getInitProperties(){
		InputStream is=InitUtil.class.getClassLoader().getResourceAsStream(propFileName);
		try {
			props.load(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return props;
	}
	
	/**
	 功能:獲得hibernate的默認schema
	 @author harold
	 @return
	 */
	public static String getDefaultSchema(){
		return InitUtil.getInitProperties().getProperty("hibernate.default_schema");
	}
	
	/**
	 功能:判斷schema是否爲空
	 @author harold
	 @return
	 */
	public static boolean isSchemaNullOrBlank() {
		String src = InitUtil.getDefaultSchema();
        if (src == null) {
            return true;
        } else if (src.trim().length() < 1) {
            return true;
        } else {
            return false;
        }
    }




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章