同义词和属主问题

来源:互联网 发布:简单的shell编程 编辑:程序博客网 时间:2024/04/28 09:45

      工作中遇到一个数据库的问题,有关同义词和属主的,由于自己对这块知识不了解,所以整理了一下,理了理思路~


      先说明一下,同义词这个东西,在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;        }    }




0 0