今天在阅读Oracle官方文档的时候,读到schema的基本概念,这就让我产生了一个疑问:user和schema两者之间到底有什么区别?为了更深层次的理解二者之间的区别和联系,以下是官方文档中关于user和schema的解释: 

            “A schema is a collection of database objects. A schema is owned by a database user and has the same name as that user. Schema objects are the logical structures that directly refer to the database’s data. Schema objects include structures like tables, views, and indexes.(There is no relationship between a tablespace and a schema. Objects in the same schema can be in different tablespaces, and a tablespace can hold objects from different schemas.)”

“A user is a name defined in the database that can connect to and access objects. Schemas and users help database administrators manage database security.”

  官方文档里面说得比较明白:

schema是数据对象的集合,包括像表、视图、索引、同义词等等都可以说是schema的对象。但不够生动,网上有篇文章里面把schema和user的关系用一个形象的比喻阐述得非常透彻,引用如下: 
  “user即Oracle中的用户,和所有系统的中用户概念类似,用户所持有的是系统的权限及资源;而schema所涵盖的是各种对象,它包含了表、函数、包等等对象的“所在地”,并不包括对他们的权限控制。

Oracle中的schema就是指一个用户下所有对象的集合,schema本身不能理解成一个对象,oracle并没有提供创建schema的语法,schema也并不是在创建user时就创建,而是在该用户下创建第一个对象之后schema也随之产生,只要user下存在对象,schema就一定存在,user下如果不存在对象,schema也不存在;如果创建一个新用户,该用户下如果没有对象则schema不存在,如果创建一个对象则和用户同名的schema也随之产生。实际上在使用上,shcema与user完全一样,没有什么区别,在出现schema名的地方也可以出现user名。

在数据库中 一个对象的完整名称为schema.object,而不属user.object。类似如果我们在创建对象时不指定该对象的schema,在该对象的schema为用户的缺省schema。
      好比一个房子,里面放满了家具,对这些家具有支配权的是房子的主人(user),而不是房子(schema)。你可以也是一个房子的主人(user),拥有自己的房子(schema).可以通过alter session的方式进入别人的房子。如果你没有特别指定的话,你所做的操作都是针对你当前所在房子中的东西。至于你是否有权限使用(select)、搬动(update)或者拿走(delete)这些家具就看这个房子的主人有没有给你这样的权限了,或者你是整个大厦(DB)的老大(DBA)。alter session set schema可以用来代替synonyms。如果你想调用其他schema的对象(有权限的前提下),但并没有建synonym,同时又不想把其他 schema名字放入代码中,就可以首先使用alter session set schema=<其他schema名字>。”

  这段文字说得非常生动,把user和schema的区别阐述得很透彻,下面通过具体的例子来加深对user和schema两者区别的认识:

第一步,以sys用户登陆SQL并建立普通用户wjqseiang 
  [oracle@seiang11g ~]$ sqlplus / as sysdba 
  SYS@seiang11g> create user wjq identified by wjq; 
  User created.

  SYS@seiang11g> create user seiang identified by seiang; 
  User created.

第二步,赋予一些基本的权限给新建的用户wjqseiang 
  SYS@seiang11g> grant connect,create table,resource to wjq,seiang; 
  Grant succeeded.

第三步,以wjq用户登陆,创建一张表并插入数据: 
  SYS@seiang11g> conn wjq/wjq 
  Connected.

  WJQ@seiang11g> create table t (id int); 
  Table created.

  WJQ@seiang11g> insert into t values(1); 
  1 row created.

  WJQ@seiang11g> commit; 
  Commit complete.

第四步,以seiang用户登陆,看能否查询wjq用户所建表里面的数据: 
  SYS@seiang11g>conn seiang/seiang 
  Connected.

  SEIANG@seiang11g> select table_name from user_tables; 
  no rows selected

  SEIANG@seiang11g> show user; 
  USER is "SEIANG"

  SEIANG@seiang11g> select * from wjq.t; 
  select * from wjq.t 
  * 
  ERROR at line 1: 
  ORA-00942: table or view does not exist 
  从以上结果可以看出,用户 seiang无法查看用户wjq所建表里面的内容,甚至被告知没有这张表。

第五步,修改当前schemawjq,并继续查询: 
  SEIANG@seiang11g> alter session set current_schema=wjq; 
  Session altered.

  SEIANG@seiang11g> show user; 
  USER is "SEIANG"

  SEIANG@seiang11g> select * from wjq.t; 
  select * from wjq.t 
  * 
  ERROR at line 1: 
  ORA-00942: table or view does not exist 
  仍然不能查看。

第六步,以wjq用户登陆,赋予seiang用户查看t表的权限: 
  SYS@seiang11g> conn wjq/wjq 
  Connected.

  WJQ@seiang11g> grant select on t to seiang; 
  Grant succeeded.

第七步,以seiang用户登陆,查看wjq用户的t表: 
  SYS@seiang11g> conn seiang/seiang 
  Connected.

  SEIANG@seiang11g>select * from wjq.t; 
  ID 
  ---------- 
  1

  更简单的,将当前schema更改为seiang,可以简化查询过程: 
  SEIANG@seiang11g> alter session set current_schema=wjq; 
  Session altered.

  SEIANG@seiang11g> select * from t; 
  ID 
  ---------- 
  1 
  这个实验下来,对user和schema的区别和联系应该有了进一步的理解了。

04-22 13:42