同义词和属主问题

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


      先说明一下,同义词这个东西,在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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值