Oracle中的架构,用户和功能ID

时间:2011-08-04 12:08:05

标签: oracle schema func

我在oracle中对架构,用户和功能id感到很困惑。让我考虑两个不同的案例

案例I:

让我们考虑SCOTT@ORCL。如果我们认为SCOTT是用户。在创建用户时,它将创建一个模式。纠正我如果我错了。在这种情况下,当我们创建SCOTT用户时,就创建了SCOTT模式。假设我们创建另一个模式说X.这可能是SCOTT用户拥有X架构吗?

案例II:

让我们考虑SCOTT@ORCL。如果我们认为SCOTT是仅由架构命令创建的架构i-e。如果是这样的话那么对于任何将拥有它的用户来说,什么是模式的使用。

我听说oracle函数ID是一个连接多个用户/模式(我不知道我是否可以将schema / user放在这里)的数据库。 b / w oracle功能ID与用户/架构有区别吗?

2 个答案:

答案 0 :(得分:9)

许多人认为这个话题令人困惑,因为我们倾向于互相围绕USER和SCHEMA,当它们实际上是相互关联的实体时。

模式是用户拥有的数据库对象的集合。当我们创建用户时,我们会同时创建他们的架构。最初他们的架构是空的。

很容易证明USER和SCHEMA是不同的,因为我们更改了会话中的当前架构。这只意味着我们可以在另一个用户的模式中引用对象,而不必使用所有者的名称作为前缀。

SQL> desc t1
 Name                                      Null?    Type
 ----------------------------------------- -------- -------------
 ID                                                 NUMBER

SQL> alter session set current_schema=APC
  2  /

Session altered.

SQL> desc t1
ERROR:
ORA-04043: object t1 does not exist

SQL> sho user
USER is "X"
SQL>

在这种情况下,APC没有一个名为T1的表,或者他没有将它授予X. X可以看到自己的表的唯一方法是在它前面加上自己的名字,或者切换当前的模式回到自己身边。


要回答您的第一个问题,架构始终与用户具有相同的名称。所以SCOTT不可能拥有架构X;模式X由用户X拥有。

要回答第二个问题,没有用户就无法创建架构。

是的,有一个CREATE SCHEMA命令,但这需要事先创建用户。它实际上不是创建模式而是创建多个数据库对象。实际上,它更像是一个ADD OBJECTS TO SCHEMA命令。

SQL> conn sys as sysdba
Enter password:
Connected.

SQL> create user x identified by x
  2  default tablespace users quota 10m on users
  3  /

User created.

SQL> grant create session, create table to x
  2  /

Grant succeeded.

SQL> conn x/x
Connected.

SQL> create schema authorization x
  2      create table t1 (id number)
  3      create table t2 (id number)
  4  /

Schema created.

SQL> select table_name from user_tables
  2  /

TABLE_NAME
------------------------------
T1
T2

SQL>

CREATE SCHEMA命令非常有限:我们可以创建表,视图和索引,并授予对象权限。它的优点就是我们可以在单个事务中创建多个对象,以便在失败时回滚所有创建。当我们单独运行每个create语句时,这是不可能的。


当您提及“功能ID”时,不确定您在想什么。它不是Oracle功能的标准部分。

答案 1 :(得分:1)

这并未定义所有者和架构之间的区别。

但是我一直在努力创造N个用户的想法....当我希望这些用户中的每个用户“消费”(又称使用)单个模式时。

这个人展示了如何做到这一点(有N个用户......被“重定向”到一个模式。

我也会粘贴他的代码,以防万一URL链接在将来死亡。

http://www.oracle-base.com/articles/misc/schema-owners-and-application-users.php

他有第二种“同义词”方法。但我只是粘贴了CURRENT_SCHEMA版本。 再说一遍,我对此不予置信。我只是讨厌当有人说“你的回答是在这个链接上”和BOOM时,链接已经死了。 :其中

............................................... .......

(来自http://www.oracle-base.com/articles/misc/schema-owners-and-application-users.php

CURRENT_SCHEMA方法

此方法使用CURRENT_SCHEMA会话属性自动将应用程序用户指向正确的架构。

首先,我们创建架构所有者和应用程序用户。

CONN sys/password AS SYSDBA

-- Remove existing users and roles with the same names.
DROP USER schema_owner CASCADE;
DROP USER app_user CASCADE;
DROP ROLE schema_rw_role;
DROP ROLE schema_ro_role;

-- Schema owner.
CREATE USER schema_owner IDENTIFIED BY password
  DEFAULT TABLESPACE users
  TEMPORARY TABLESPACE temp
  QUOTA UNLIMITED ON users;

GRANT CONNECT, CREATE TABLE TO schema_owner;

-- Application user.
CREATE USER app_user IDENTIFIED BY password
  DEFAULT TABLESPACE users
  TEMPORARY TABLESPACE temp;

GRANT CONNECT TO app_user;

请注意,应用程序用户可以连接,但没有任何表空间配额或权限来创建对象。

接下来,我们创建一些角色以允许读写和只读访问。

CREATE ROLE schema_rw_role;
CREATE ROLE schema_ro_role;

我们希望为应用程序用户提供对架构对象的读写权限,因此我们授予相关角色。

GRANT schema_rw_role TO app_user;

我们需要确保应用程序用户的默认架构指向架构所有者,因此我们创建了一个AFTER LOGON触发器来为我们执行此操作。

CREATE OR REPLACE TRIGGER app_user.after_logon_trg
AFTER LOGON ON app_user.SCHEMA
BEGIN
  DBMS_APPLICATION_INFO.set_module(USER, 'Initialized');
  EXECUTE IMMEDIATE 'ALTER SESSION SET current_schema=SCHEMA_OWNER';
END;
/

现在我们已准备好在架构所有者中创建一个对象。

CONN schema_owner/password

CREATE TABLE test_tab (
  id          NUMBER,
  description VARCHAR2(50),
  CONSTRAINT test_tab_pk PRIMARY KEY (id)
);

GRANT SELECT ON test_tab TO schema_ro_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON test_tab TO schema_rw_role;

请注意如何将权限授予相关角色。如果没有这个,应用程序用户将无法看到这些对象。我们现在有一个正常运行的架构所有者和应用程序用户。

SQL> CONN app_user/password
Connected.
SQL> DESC test_tab
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 ID                                                    NOT NULL NUMBER
 DESCRIPTION                                                    VARCHAR2(50)

SQL>

此方法非常适用于应用程序用户只是主模式的替代入口点,不需要自己的对象。