1. 程式人生 > >ORACLE中的兩個概念:user和schema的區別和聯絡

ORACLE中的兩個概念:user和schema的區別和聯絡

今天重讀ORACLE官方文件《concepts》,讀到schema的基本概念,對它的理解更進一層,官方文件中關於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.)”

  官方文件裡面說得比較明白,schema是資料物件的集合,包括像表、檢視、索引、同義詞等等都可以說是schema的物件。但不夠生動,網上有篇文章裡面把schema和user的關係用一個形象的比喻闡述得非常透徹,引用如下:

  “user即Oracle中的使用者,和所有系統的中使用者概念類似,使用者所持有的是系統的許可權及資源;而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並建立普通使用者storm和penguin:

  $ sqlplus / as sysdba

  SQL> create user storm identified by storm;

  User created.

  SQL> create user penguin identified by penguin;

  User created.

  第二步,賦予一些基本的許可權給新建的使用者storm和penguin:

  SQL> grant connect,create table,resource to storm,penguin;

  Grant succeeded.

  第三步,以storm使用者登陸,建立一張表並插入資料:

  SQL> conn storm/storm

  Connected.

  SQL> create table t (id int);

  Table created.

  SQL> insert into t values(1);

  1 row created.

  SQL> commit;

  Commit complete.

  第四步,以penguin使用者登陸,看能否查詢storm使用者所建表裡面的資料:

  SQL> conn penguin/penguin

  Connected.

  SQL> select table_name from user_tables;

  no rows selected

  SQL> show user;

  USER is "PENGUIN"

  SQL> select * from storm.t;

  select * from storm.t

  *

  ERROR at line 1:

  ORA-00942: table or view does not exist

  從以上結果可以看出,使用者 penguin無法檢視使用者storm所建表裡面的內容,甚至被告知沒有這張表。

  第五步,修改當前schema為storm,並繼續查詢:

  SQL> alter session set current_schema=storm;

  Session altered.

  SQL> show user;

  USER is "PENGUIN"

  SQL> select * from storm.t;

  select * from storm.t

  *

  ERROR at line 1:

  ORA-00942: table or view does not exist

  仍然不能檢視。

  第六步,以storm使用者登陸,賦予penguin使用者檢視t表的許可權:

  SQL> conn storm/storm

  Connected.

  SQL> grant select on t to penguin;

  Grant succeeded.

  第七步,以penguin使用者登陸,檢視storm使用者的t表:

  SQL> conn penguin/penguin

  Connected.

  SQL> select * from storm.t;

  ID

  ----------

  1

  更簡單的,將當前schema更改為storm,可以簡化查詢過程:

  SQL> alter session set current_schema=storm;

  Session altered.

  SQL> select * from t;

  ID

  ----------

  1

  這個實驗下來,對user和schema的區別和聯絡應該有了進一步的理解了。

==========

有的人還是對schema的真正含義不太理解,現在我再次整理了一下,希望對大家有所幫助。

我們先來看一下他們的定義:
A schema is a collection of database objects (used by a user.).
Schema objects are the logical structures that directly refer to the database’s data.
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裡面包含了各種物件如tables, views, sequences, stored procedures, synonyms, indexes, clusters, and database links。

一個使用者一般對應一個schema,該使用者的schema名等於使用者名稱,並作為該使用者預設schema。這也就是我們在企業管理器的方案下看到schema名都為資料庫使用者名稱的原因。Oracle資料庫中不能新建立一個schema,要想建立一個schema,只能通過建立一個使用者的方法解決(Oracle中雖然有create schema語句,但是它並不是用來建立一個schema的),在建立一個使用者的同時為這個使用者建立一個與使用者名稱同名的schem並作為該使用者的預設shcema。即schema的個數同user的個數相同,而且schema名字同user名字一一 對應並且相同,所有我們可以稱schema為user的別名,雖然這樣說並不準確,但是更容易理解一些。

一個使用者有一個預設的schema,其schema名就等於使用者名稱,當然一個使用者還可以使用其他的schema。如果我們訪問一個表時,沒有指明該表屬於哪一個schema中的,系統就會自動給我們在表上加上預設的sheman名。比如我們在訪問資料庫時,訪問scott使用者下的emp表,通過select * from emp; 其實,這sql語句的完整寫法為select * from scott.emp。在資料庫中一個物件的完整名稱為schema.object,而不屬user.object。類似如果我們在建立物件時不指定該物件的schema,在該物件的schema為使用者的預設schema。這就像一個使用者有一個預設的表空間,但是該使用者還可以使用其他的表空間,如果我們在建立物件時不指定表空間,則物件儲存在預設表空間中,要想讓物件儲存在其他表空間中,我們需要在建立物件時指定該物件的表空間。

咳,說了這麼多,給大家舉個例子,否則,一切枯燥無味!
SQL> Gruant dba to scott

SQL> create table test(name char(10));
Table created.

SQL> create table system.test(name char(10));
Table created.

SQL> insert into test values('scott');
1 row created.

SQL> insert into system.test values('system');
1 row created.

SQL> commit;
Commit complete.

SQL> conn system/manager
Connected.

SQL> select * from test;
NAME
----------
system

SQL> ALTER SESSION SET CURRENT_SCHEMA = scott; --改變使用者預設schema名
Session altered.

SQL> select * from test;
NAME
----------
scott

SQL> select owner ,table_name from dba_tables where table_name=upper('test');
OWNER TABLE_NAME
------------------------------ ------------------------------
SCOTT TEST
SYSTEM TEST
--上面這個查詢就是我說將schema作為user的別名的依據。實際上在使用上,shcema與user完全一樣,沒有什麼區別,在出現schema名的地方也可以出現user名。

表空間:

一個表空間就是一片磁碟區域,他又一個或者多個磁碟檔案組成,一個表空間可以容納許多表、索引或者簇等
每個表空間又一個預製的打一磁碟區域稱為初始區間(initial extent)用完這個區間厚在用下一個,知道用完表空間,這時候需要對錶空間進行擴充套件,增加資料文件或者擴大已經存在的資料檔案


instance是一大坨記憶體sga,pga....和後臺的程序smon pmon.....組成的一個大的應用。
schema就是一個使用者和他下面的所有物件。。
tablspace 邏輯上用來放objects.物理上對應磁碟上的資料檔案或者裸裝置。

在Oracle中,結合邏輯儲存與物理儲存的概念,我們可以這樣來理解資料庫、表空間、SCHEMA、資料檔案這些概念:
資料庫是一個大圈,裡面圈著的是表空間,表空間裡面是資料檔案,那麼schema是什麼呢?schema是一個邏輯概念,是一個集合,但schema並不是一個物件,oracle也並沒有提供建立schema的語法。

schema:
一般而言,一個使用者就對應一個schema,該使用者的schema名等於使用者名稱,並作為該使用者預設schema,使用者是不能建立schema的,schema在建立使用者的時候建立,並可以指定使用者的各種表空間(這點與PostgreSQL是不同,PostgreSQL是可以建立schema並指派給某個使用者)。當前連線到資料庫上的使用者建立的所有資料庫物件預設都屬於這個schema(即在不指明schema的情況下),比如若使用者scott連線到資料庫,然後create table test(id int not null)建立表,那麼這個表被建立在了scott這個schema中;但若這樣create kanon.table test(id int not null)的話,這個表被建立在了kanon這個schema中,當然前提是許可權允許。
建立使用者的方法是這樣的:
create user 使用者名稱 identified by 密碼
default tablespace 表空間名
temporary tablespace 表空間名
quota 限額 (建議建立的時候指明表空間名)
由此來看,schema是一個邏輯概念。
但一定要注意一點:schema好像並不是在建立user時就建立的,而是在該使用者建立了第一個物件之後才將schema真正建立的,只有user下存在物件,他對應的schema才會存在,如果user下不存在任何物件了,schema也就不存在了;

資料庫:
在oracle中,資料庫是由表空間來組成的,而表空間裡面是具體的物理檔案---資料檔案。我們可以建立資料庫併為其指定各種表空間。

表空間:
這是個邏輯概念,本質上是一個或者多個數據檔案的集合。

資料檔案:
具體儲存資料的物理檔案,是一個物理概念。

一個數據檔案只能屬於一個表空間,一個表空間可以包含一個或多個數據檔案。一個數據庫由多個表空間組成,一個表空間只能屬於一個數據庫。

若還不理解,下面是我從網上摘的一個比喻,很形象的解釋了什麼是Database,什麼是Schema,什麼是Table,什麼是列,什麼是行,什麼是User,不妨一看。
“我們可以把Database看作是一個大倉庫,倉庫分了很多很多的房間,Schema就是其中的房間,一個Schema代表一個房間,Table可以看作是每個Schema中的床,Table(床)被放入每個房間中,不能放置在房間之外,那豈不是晚上睡覺無家可歸了,然後床上可以放置很多物品,就好比 Table上可以放置很多列和行一樣,資料庫中儲存資料的基本單元是Table,現實中每個倉庫放置物品的基本單位就是床, User就是每個Schema的主人,(所以Schema包含的是Object,而不是User),user和schema是一一對應的,每個user在沒有特別指定下只能使用自己schema(房間)的東西,如果一個user想使用其他schema(房間)的東西,那就要看那個schema(房間)的user(主人)有沒有給你這個許可權了,或者看這個倉庫的老大(DBA)有沒有給你這個許可權了。換句話說,如果你是某個倉庫的主人,那麼這個倉庫的使用權和倉庫中的所有東西都是你的(包括房間),你有完全的操作權,可以扔掉不用的東西從每個房間,也可以放置一些有用的東西到某一個房間,你還可以給每個User分配具體的許可權,也就是他到某一個房間能做些什麼,是隻能看(Read-Only),還是可以像主人一樣有所有的控制權(R/W),這個就要看這個User所對應的角色Role了。”---摘自網路

=============
常被oracle的幾個概念搞得很暈,和公司做pl/sql的同事討論後,又到網上搜索下,現將個人對這幾個概念的理解做個筆記:
先通俗的解釋下資料庫這個概念,資料庫就是儲存在磁碟上的檔案,這些檔案中儲存的資料有一定的物理結構和邏輯結構。
資料庫名 就是資料庫的名稱標識,如myOracle, 這種叫法一般只適用於單機;
全域性資料庫名 就是資料庫處於一個網路中的名稱標識。比如資料庫宿主機的域為mydomain, 
則資料庫的全域性資料庫名為myOracle.mydomain;
實際上myOracle和myOracle.mydomain兩者指的是同一個資料庫.
即:全域性資料庫名 = 資料庫名+"."+網路位置(宿主機所在的域)
設定全域資料庫名稱Oracle9i 的全域資料庫名稱由「資料庫名稱」與「網域名稱」所組成,其中「資料庫名稱」設定於 DB_NAME 起始引數,而「網域名稱」則是設定於 DB_DOMAIN 引數。這兩個引數合併之後就可以在網際網路上唯一識別每一個 Oracle9i 資料庫。舉例來說,假設我們欲建立的 Oracle9i 資料庫之全域資料庫名稱為 mydb.uuu.com.tw,那麼可在起始引數檔內設定下列兩引數:DB_NAME = mydbDB_DOMAIN = uuu.com.twTips: 您可以執行 ALTER DATABASE RENAME GLOBAL_NAME 指令更改 Oracle9i 資料庫的全域資料庫名稱;在您更改 DB_NAME 與 DB_DOMAIN 這兩個起始引數後必須將 Oracle9i 資料庫重新啟用才會生效。此外,控制檔也必須重新建立。關於 DB_NAME 起始引數DB_NAME必須是文字字串,且不能超過 8 個字元。在建立資料庫的過程中,DB_NAME設定值會記錄在資料檔案、控制檔案、以及重置日誌檔案之中。如果您啟用 Oracle9i Instance 的時候,起始引數檔內設定的DB_NAME不同於控制檔案內所紀錄的,那麼資料庫將無法啟用。關於 DB_DOMAIN 起始引數DB_DOMAIN通常是資料庫主機所在位置的網域名稱。如果您欲建立的資料庫將加入分散式資料庫運算環境,請特別注意此引數的設定。
SID = Oracle例項
SID是Oracle例項的唯一名稱標識,
使用者去訪問資料庫,實際上是向某一個Oracle例項傳送請求,oracle例項負責向資料庫獲取資料。
Oracle例項 = 記憶體結構+後臺程序,所以Oracle例項是臨時性的;
可以通過startup nomount去啟動例項,但是注意這時Oracle資料庫並沒有啟動,需要用open去啟動資料庫;
一個例項只能對應一個數據庫,一個數據庫可以用多個例項;
名稱空間,有點複雜。
名稱空間定義了一組物件型別,在名稱空間裡,物件的名字必須是唯一的,當然,在不同的名稱空間裡,是可以使用相同的的名字的。
下面的物件型別共享同一個名稱空間:
• Tables
• Views
• Sequences
• Private synonyms
• Stand-alone procedures
• Stand-alone stored functions
• Packages
• Materialized views
• User-defined types
因此,如果資料庫中有一個表叫做myObject1,那麼就不能再建立一個叫做myObject1的檢視,至少,在一個schema中是不可能出現這種現象的;
下面的物件型別有各自的名稱空間:
• Indexes
• Constraints
• Clusters
• Database triggers
• Private database links
• Dimensions
所以你可以建立一個叫做myObject1的索引,即使在相同的schema中;
不受Schema侷限的物件型別(Non schema objects)有它們自己的名稱空間,如下:
• User roles
• Public synonyms
• Public database links
• Tablespaces
• Profiles
• Parameter files (PFILEs) and server parameter files (SPFILEs)
所以兩個Non-schema objects可以用相同的名字。
Schema是基於使用者的, 在資料庫中建立一個使用者,就建立了一個和使用者名稱相同的Shema。

Namespace是基於資料庫的.