用户和模式在Oracle中有什么区别?

359

在Oracle中,用户和模式之间有什么区别?


17
+1 我也一直想知道这个区别 :-/. - sleske
9
下面有一篇有趣的文章,它消除了所有的疑惑:http://radiofreetooting.blogspot.com/2007/02/user-schema.html - Sandeep Jindal
10
Oracle模式类似于Windows操作系统中的“我的文档”文件夹。用户可以授予其他用户查看其模式中的内容的权限。Oracle模式本质上是用户的工作区。 - Tarzan
3
还在DBA上讨论过:http://dba.stackexchange.com/questions/37012/difference-between-database-vs-user-vs-schema。 - user565869
15个回答

152

来自Ask Tom

你应该将模式视为用户帐户和其中所有对象的集合,就像所有意图的模式一样。

SCOTT是一个包括EMP、DEPT和BONUS表以及其他授权和其他内容的模式。

SYS是一个包括大量表、视图、授权等等的模式。

SYSTEM是一个模式.....

从技术上讲——模式是数据库使用的元数据(数据字典)集,通常使用DDL生成。模式定义了数据库的属性,例如表、列和属性。数据库模式是数据库中数据的描述。


56
就所有意图和目的而言,将用户(user)=模式(schema)=用户(user)=模式(schema)视为同一事物。 - sengs
6
但是我可以让两个用户使用相同的模式吗? - John John Pichler
10
如果你的意思是“单个模式中的对象可以由多个用户‘拥有’”,答案是否定的。如果你的意思是“单个模式中的对象可以被多个用户使用”,那么答案肯定是肯定的。 - Mahesh

112

我认为问题在于Oracle对术语schema的使用略有不同于一般含义。

  1. Oracle的schema(如Nebakanezer的回答中所述):基本上是由用户账户拥有的所有表和其他对象组成的集合,因此与用户账户大致等同。
  2. 一般情况下的Schema:组成给定系统/应用程序数据库的所有表、存储过程等内容(例如,“开发人员应该与数据库管理员讨论我们新应用程序的模式。”)

在第2点中提到的模式与第1点中提到的模式类似,但并不完全相同。例如,对于使用多个DB账户的应用程序,一个第2点中的模式可能由多个Oracle模式组成 :-).

此外,schema在其他语境中也可以表示一堆其他不太相关的事物(例如,在数学中)。

Oracle应该使用类似于“userarea”或“accountobjects”的术语,而不是重载“schema”...


据我所知,这个问题是关于Oracle的,而不是关于MS SQL的。 - peterh
3
我同意,Oracle不应该使用“模式(schema)”这个术语,对于刚接触Oracle的人来说,这让事情变得很尴尬。可以考虑使用类似“模式访问”之类的术语,因为它提供对(真实)模式的部分(或全部)可重用访问。 - Gerry

70

来自WikiAnswers:

  • 一个 schema 是数据库对象的集合,包括逻辑结构,如表、视图、序列、存储过程、同义词、索引、簇和数据库链接。
  • 一个用户拥有一个 schema。
  • 一个用户和一个 schema 有相同的名称。
  • CREATE USER 命令创建用户。它还会自动为该用户创建一个 schema。
  • CREATE SCHEMA 命令不会像其名称暗示的那样创建一个“schema”,而是允许您在单个事务中创建多个表和视图以及执行多个授权操作。
  • 就所有实际目的而言,您可以认为一个用户是一个 schema,一个 schema 是一个用户。

此外,如果用户有访问权限,他们可以访问其他 schema 中的对象。


3
关于 CREATE SCHEMA,你提到的很有道理——我认为这个命令名称选择不佳! - Jeffrey Kemp
4
“CREATE SCHEMA” 命令并不像它说的那样创建一个“schema”,这正是导致99%的混淆的原因。这个短语很好地澄清了这一点。谢谢。 - granadaCoder
3
关于CREATE SCHEMA的注释:“Oracle之所以有它,是因为ANSI标准规定必须有它。” - user123444555621
我认为这是最好的答案。 - hagrawal7777

52

通常我们把用户看作是一个具有用户名和密码的实体,可以登录并访问系统中的某些对象,而模式则是用户家目录的数据库版本。例如,用户"foo"通常在模式"foo"下创建一些东西。如果用户"foo"创建或引用表"bar",那么Oracle会认为这个用户指的是"foo.bar"。


2
简洁的描述,但是为什么你使用了 "foo" 来代表用户和模式?它们必须相同吗? - JonnyRaa
2
在Oracle中,USER是账户名,SCHEMA是该用户拥有的对象集合。尽管Oracle在CREATE USER语句中创建SCHEMA对象,并且SCHEMA与USER具有相同的名称,但它们不是同一物。当然,混淆部分源于USER和SCHEMA之间存在一对一的对应关系,并且用户的模式与其名称相同。 - Mahesh

20

这个答案没有定义所有者和schema之间的区别,但我认为它有助于讨论。

在我自己的思考世界里:

我曾经苦恼于创建N个用户,我希望每个用户都可以“消耗”(即使用)一个单独的schema。

Tim在oracle-base.com上展示了如何做到这一点(拥有N个用户,并将这些用户“重定向”到一个单独的schema)。

他还有第二种“同义词”方法(未列在此处)。 我只引用了CURRENT_SCHEMA版本(他的方法之一):

CURRENT_SCHEMA方法

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

首先,我们创建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>

如果应用程序用户只是主架构的替代入口点,并不需要自己的对象,那么这种方法是理想的。


1
请注意,使用角色可能无法解决 PL/SQL 代码的权限问题。当存储过程被编译和运行时,对象授权到角色的传播方式并不直观。然而,我点赞了这个答案,因为这种方法真的很棒,但据我所知,它鲜为人知且很少被使用。 - Andrew Wolfe

19

非常简单。

If USER has OBJECTS
then call it SCHEMA
else
     call it USER
end if;
一个用户可能被授予访问不同用户拥有的模式对象的权限。

1
实际上,混淆是由于人们将“用户”称为“模式”而造成的。因为正如你所解释的那样,用户可能并不是模式。一个用户可以简单地是访问其他用户模式的用户。 - Sandeep Jindal

3

--用户和模式

用户和模式这两个词是可以互换使用的,这就是为什么大多数人对这些词感到困惑。下面我解释一下它们之间的区别。

--用户 用户是连接数据库(服务器)的账户。我们可以通过使用CREATE USER user_name IDENTIFIED BY password来创建用户。

--模式

实际上,Oracle数据库包含逻辑和物理结构来处理数据。模式也是处理数据库(内存组件)中的数据的逻辑结构。当用户被创建时,Oracle会自动创建一个模式。它包含与该模式关联的用户创建的所有对象。例如,如果我创建了一个名为santhosh的用户,Oracle会创建一个名为santhosh的模式,Oracle将所有由用户santhosh创建的对象存储在santhosh模式中。

我们可以使用CREATE SCHEMA语句来创建模式,但Oracle会自动为该模式创建一个用户。

我们可以使用DROP SCHEMA schema_name RESTRICT语句来删除模式,但它不能删除包含对象的模式,因此要删除模式,它必须为空。这里的restrict关键字强制指定没有对象的模式。

如果我们试图删除一个包含在其模式中的用户对象,我们必须指定CASCADE关键字,因为Oracle不允许您删除包含对象的用户。 DROP USER user_name CASCADE 因此,Oracle会删除模式中的对象,然后自动删除用户,其他模式中引用此模式对象的对象(如视图和私有同义词)将变为无效状态。

3

模式是关于感兴趣的领域/思想的DB.objects封装,由一个用户拥有。然后被其他带有禁止角色的用户/应用程序共享。因此,用户不需要拥有模式,但模式需要有所有者。


1
基于我对Oracle的一点了解,用户(USER)和模式(SCHEMA)有些相似。但是也存在一个主要区别。如果“用户”拥有任何对象,则可以将其称为模式,否则...它仅保持为“用户”。一旦用户拥有至少一个对象,那么根据您上面所有定义的原则......用户现在可以被称为模式。

1
对于大多数熟悉MariaDB或MySQL的人来说,这似乎有点令人困惑,因为在MariaDB或MySQL中,它们具有不同的模式(包括不同的表、视图、PLSQL块和DB对象等),而用户是可以访问这些模式的帐户。因此,没有特定的用户属于任何特定的模式。必须授予该模式权限,然后用户才能访问它。在像MySQL和MariaDB这样的数据库中,用户和模式是分开的。
在Oracle中,模式和用户几乎被视为相同。要使用该模式,您需要获得权限,在这里您会感到模式名称只是用户名。可以跨模式授予权限以访问来自不同模式的不同数据库对象。在Oracle中,我们可以说用户拥有一个模式,因为当您创建用户时,您为其创建DB对象,反之亦然。

谢谢你的回答。角色也是模式对象吗? - Mehdi Charife

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接