用会话模式管理整合Oracle数据库

日期: 2011-12-18 作者:Jeff McCormick翻译:冯昀晖 来源:TechTarget中国 英文

Oracle数据库整合系列文章分两部分,这是第二部分。第一部分讲的是数据库蔓延以及为什么数据库整合是一种模式转变。   Oracle提供了几个内建的功能来支持数据库整合。其中一个功能就是会话模式管理(session schema management)。

下面的例子将展示会话级模式控制如何透明地支持多个模式来促进多租户共享相同的数据库。   ABC Gum公司的客户信息系统在软件开发生命周期(SDLC)的每个环节都在不同的数据库中建立了实例。在努力提升效率并降低成本的过程中,该公司正在努力整合所有非生产用的模式到单个数据库中。要取得成功,该项目必须满足下面两个需求:项目管理控制和不做应用程序改变……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

Oracle数据库整合系列文章分两部分,这是第二部分。第一部分讲的是数据库蔓延以及为什么数据库整合是一种模式转变。

  Oracle提供了几个内建的功能来支持数据库整合。其中一个功能就是会话模式管理(session schema management)。下面的例子将展示会话级模式控制如何透明地支持多个模式来促进多租户共享相同的数据库。

  ABC Gum公司的客户信息系统在软件开发生命周期(SDLC)的每个环节都在不同的数据库中建立了实例。在努力提升效率并降低成本的过程中,该公司正在努力整合所有非生产用的模式到单个数据库中。要取得成功,该项目必须满足下面两个需求:项目管理控制和不做应用程序改变。

点击放大

  DBA团队首先考虑了应用程序的影响,特别是没有前缀模式修饰的SQL代码。尽管有类似对象的独立模式提供了逻辑分离,但整合也会带来模式名称冲突的问题。如果目前的三个SDLC环境共享同一个数据库,那就会有三个“customer”表了。DBA团队长期强调使用公有同名(public synonyms)来解决没有前缀模式对象引用的最佳实践将不再有效。他们考虑为每个开发人员创建私有同名(private synonyms),把它们赋给单个SDLC环境。然而,开发人员会频繁地在各个环境之间切换,会忘记删除并重建他们的私有同名,这会危害完整性并带来混乱。看来同名不是这种动态开发环境的解决办法了。

  好在Oracle公司给用户提供了在会话内改变模式的功能支持,无需模式对象的修饰引用。请看:

ALTER SESSION SET CURRENT_SCHEMA = ;

  “CURRENT_SCHEMA”参数把当前会话模式改成了指定模式。在会话期间,随后对模式对象的无前缀描述引用将被解释为指定模式下的对象。

  这一设置在会话持续期间一直有效,除非你再使用一次“ALTER”命令做了改变。此设置为非当前用户模式的模式对象操作提供了便捷途径,这样就无须指定对象的所属模式名了。该设置改变了当前模式,但是它并没有改变会话用户或者当前用户,也不会在本会话期间给会话用户任何额外的系统权限或者对象权限。

  Oracle数据库SQL 语言参考。

  下面的代码展示了开发人员模式如何在会话期间改变成三个ABC应用模式之一,而无需修改未加模式修饰的SQL代码。作为额外的收获,团队把这三种“状态”查询表整合成了一个,使用公有同名来为开发人员提供访问,而不管他们当前的模式。通过使用安全角色,单个用户可以在多个模式中有权限,这样就不需要多个Oracle账户了。

-- Logon as Jeff the developer
select substr(sys_context('USERENV', 'SESSION_USER')  ,1,10) "Session User"
      ,substr(sys_context('USERENV', 'CURRENT_SCHEMA'),1,10) "Current Schema"
  from dual;
Session User         Current Schema
----------------     ---------------------
JEFF                     JEFF
select customer_name from customer;
                SQL Error: ORA-00942: table or view does not exist
-- Set current schema to Development
alter session set current_schema = abc_dev;
alter session set succeeded.
select substr(sys_context('USERENV', 'SESSION_USER')  ,1,10) "Session User"
      ,substr(sys_context('USERENV', 'CURRENT_SCHEMA'),1,10) "Current Schema"
  from dual;
Session User         Current Schema
----------------     ---------------------
JEFF                     ABC_DEV 
select customer_name from customer;
CUSTOMER_NAME                 
------------------------------
Jaime
-- Set current schema to Test
alter session set current_schema = abc_test;
select substr(sys_context('USERENV', 'SESSION_USER')  ,1,10) "Session User"
      ,substr(sys_context('USERENV', 'CURRENT_SCHEMA'),1,10) "Current Schema"
  from dual;
Session User         Current Schema
----------------     ---------------------
JEFF                     ABC_TEST
alter session set succeeded.
select customer_name, state_name
 from customer inner join val_state
   on customer.state_code = val_state.state_code;
CUSTOMER_NAME              STATE_NAME                    
------------------------------    ------------------------------
Rebecca                                    Connecticut      

  对于没有前缀模式修饰的SQL代码,现在可以按正确的模式解析,该项目管理员要控制开发人员模式的分配。DBA建议采用以表为驱动的解决方案,把开发人员映射到了模式。这种模式分配是由项目管理员管理的,并在通过登陆触发器时执行。下面的代码展示了如何实现登录时赋予模式,开发人员模式被自动变成他们的身份认证模式。

-- Step 1: Create user to schema mapping table
create table abc_user_schema
 (
  abc_user    varchar2(30) not null
 ,abc_schema  varchar2(30) not null
 ,constraint  abc_user_pk primary key (abc_user) enable validate
)
organization index
pctfree 0;
-- Step 2: Populate user to schema mapping table
insert into abc_user_schema (abc_user, abc_schema) values ('JEFF','ABC_DEV');
commit;
-- Step 3: Create logon trigger
create or replace trigger abc_user_schema_assignment
  after logon
  on database when (sys_context('USERENV', 'ISDBA') = 'FALSE')
  declare
     l_session_user    abc_user_schema.abc_user%type := sys_context('USERENV', 'SESSION_USER');
     l_assigned_schema abc_user_schema.abc_schema%type;
  begin
    begin
      select abc_schema into l_assigned_schema
        from abc_user_schema
        where abc_user = l_session_user;           
      execute immediate 'ALTER SESSION SET CURRENT_SCHEMA = '|| l_assigned_schema;       
      exception
        when NO_DATA_FOUND then NULL;
        when others        then raise;
    end;
    exception
        when others then raise_application_error(-20001,'UM : Logon Trigger - Error - '||SQLERRM(sqlcode));
  end;

相关推荐