oracle中的資料庫、使用者、方案、表空間、表物件之間的關係

TZBiao發表於2013-04-22
最近在學習oracle,給我的第一個感覺就是甲骨文的體系太龐大了(因為我之前一直使用的是mysql,輕量級的資料庫)。而開始遇到的最糾結的問題,就是怎麼理清oracle中資料庫、使用者、方案、表空間、表物件之間的關係,如果這個問題搞不清楚,接下來的學習也就會雨裡霧裡了。所以,下定決心一定把它研究清楚,便開始了搜尋各種資料的旅程。
1.首先,我們先看看oracle和sqlserver的一些區別吧。oracle中的一個資料庫就是一個例項,而在sqlserver中,在一個例項下面可以建多個資料庫。從使用者方面來看,oracle的一個使用者就是一個Schema(方案,雖然這麼說不太準確,但是易於理解,後面我會詳細說明這個問題),所有的表都屬於不同的使用者,一個使用者要訪問另一個使用者的表,需要有授權,而在sqlserver中,表是在資料庫中建立的,它並不屬於某個使用者。oracle的結構是===例項->使用者->表,表是屬於某個使用者的(但是訪問時實際上用的是schema進行索引表的)所以在oracle下 建表空間,建使用者,設定使用者的預設表空間,在使用者下建表;而在sqlserver下,結構是===例項->庫->表,使用者與庫、表 獨立,sqlserver下是建庫,在庫下建表,建使用者,設定使用者訪問庫的許可權。《也可以這麼理解,oracle中有資料庫,但是不同於sqlserver,oracle的一個例項只有一個資料庫,資料庫系統的基本資訊也儲存在這個資料庫中,不像sqlserver儲存在單獨的master資料庫中》
2.現在我們再看看錶空間和方案之間的關係吧。其實它們之間的關係就是沒有關係,在一個instance下可以有多個使用者,每個使用者只能有一個schema。很多人包括我一直在想的問題就是既然schema是用來存放table object的,而表空間也是存放table object,它們之間是不是存在著某種關係呢,但是結果就是沒有關係。在資料庫建立一個使用者後,並給以這個使用者建立表或者其他物件的許可權,這時還沒有模式存在。只有當這個使用者利用這些許可權建立了屬於自己的第一個物件時,oracle為這個使用者建立一個schema,來容納這個物件以及以後建立的物件。同一個schema的objects可以儲存在不同的tablespace(表空間)中,同樣,tablespace也可以儲存不同schema的objects。schema就是一個使用者和它下面的所有物件,而表空間邏輯上用來放objects,物理上對應磁碟上的資料檔案或者裸裝置。
3.再看方案和使用者之間的關係吧。從定義中,我們可以看出方案為資料庫物件的集合,為了區分各個集合,我們需要給這個集合起個名字,這些名字也就是我們在企業管理器的方案下看到的許多類似使用者名稱的節點,這些類似使用者名稱的節點其實就是一個schema,schema裡面包含了各種物件如tables,views,sequences,stored procedures,synonyms,indexes,clusters,and database links。一個使用者一般對應一個schema,該使用者的schema名等於使用者名稱,並作為該使用者預設的schema,這就是我們在企業管理器的方案下看到的schema名都是資料庫使用者名稱的原因。oracle資料庫中不能新建立一個schema,要想建立一個schema,只能通過建立一個使用者的方法解決(oracle中的create schema語句不是用來建立schema的)。schema的個數通user的個數相同,而且schema名字和user名字一一對應並且相同,所以我們稱schema為user的別名,雖然不準確,但是容易理解。在授權情況下,一個使用者可以使用其他的schema,一個使用者只有一個預設的schema。如果我們訪問一個表時,沒有指明該表屬於哪一個schema中的,系統就會自動給我們在表上加上預設的sheman名。比如我們在訪問資料庫時,訪問scott使用者下的emp表,通過select * from emp; 其實,這sql語句的完整寫法為select * from scott.emp。在資料庫中一個物件的完整名稱為schema.object,而不屬user.object。類似如果我們在建立物件時不指定該物件的schema,在該物件的schema為使用者的預設schema。這就像一個使用者有一個預設的表空間,但是該使用者還可以使用其他的表空間,如果我們在建立物件時不指定表空間,則物件儲存在預設表空間中,要想讓物件儲存在其他表空間中,我們需要在建立物件時指定該物件的表空間。
oracle中的schema就是指一個使用者下所有物件的集合,schema本身不能理解成一個物件,oracle並沒有提供建立schema的語法,schema也並不是在建立user時就建立,而是在該使用者下建立第一個物件之後schema也隨之產生,只要user下存在物件,schema就一定存在,user下如果不存在物件,schema也不存在;這一點類似於temp tablespace group,另外也可以通過oem來觀察,如果建立一個新使用者,該使用者下如果沒有物件則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是一個邏輯概念,是一個集合,但schema不是一個物件,oracle也並沒有提供建立schema的語法。表空間也是個邏輯概念,本質上是一個或者多個資料檔案的集合。資料檔案是一個物理概念,是具體儲存資料的物理檔案。一個資料檔案只能屬於一個表空間,一個表空間可以包含一個或多個資料檔案,一個資料庫由多個表空間組成,但是一個表空間只能屬於一個資料庫。 下面有個很形象的比喻,是從網上摘的,不妨一看: 我們可以把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了。

相關文章