在學習SQL的過程中,會遇到一個讓你迷糊的Schema的概念。實際上,schema就是數據庫對象的集合,這個集合包含了各種對象如:表、視圖、存儲過程、索引等。為了區分不同的集合,就需要給不同的集合起不同的名字,默認情況下一個用戶對應一個集合,用戶的schema名等于用戶名,并作為該用戶缺省schema。所以schema集合看上去像用戶名。
如果把database看作是一個倉庫,倉庫很多房間(schema),一個schema代表一個房間,table可以看作是每個房間中的儲物柜,user是每個schema的主人,有操作數據庫中每個房間的權利,就是說每個數據庫映射的user有每個schema(房間)的鑰匙。
我們訪問一個表時,沒有指明該表屬于哪一個schema中的,系統就會自動給我們在表上加上缺省的sheman名。在數據庫中一個對象的完整名稱為schema.object,而不屬user.object。
在MySQL中創建一個Schema和創建一個Database的效果好像是一樣的,但是在sqlserver和orcal數據庫中效果又是不同的。
在SQL Server 2000中,user和schema總有一層隱含的關系,讓我們很少意識到其實user和schema是兩種完全不同的概念,假如我們在某一數據庫中創建了用戶Bosco,那么此時后臺也為我們默認的創建了schema【Bosco】,schema的名字和user的名字相同。
在SQL Server 2005中,為了向后兼容,當用sp_adduser存儲過程創建一個用戶的時候,sqlserver2005同時也創建了一個和用戶名相同的schema,然而這個存儲過程是為了向后兼容才保留的,當我們用create user創建數據庫用戶時,我們可以用該用戶指定一個已經存在的schema作為默認的schema,如果我們不指定,則該用戶所默認的schema即為dbo schema,dbo房間(schema)好比一個大的公共房間,在當前登錄用戶沒有默認schema的前提下,如果你在大倉庫中進行一些操作,比如create table,如果沒有制定特定的房間(schema),那么你的物品就只好放進公共的dbo房間(schema)了。但是如果當前登錄用戶有默認的schema,那么所做的一切操作都是在默認的schema上進行。
在Oracle數據庫中不能新建一個schema,要想創建一個schema,只能通過創建一個用戶的方法解決,在創建一個用戶的同時為這個用戶創建一個與用戶名同名的schem并作為該用戶的缺省shcema。即schema的個數同user的個數相同,而且schema名字同user名字一一 對應并且相同。
?
按照SQL標準的解釋,在SQL環境下Catalog和Schema都屬于抽象概念,可以把它們理解為一個容器或者數據庫對象命名空間中的一個層次,主要用來解決命名沖突問題。從概念上說,一個數據庫系統包含多個Catalog,每個Catalog又包含多個Schema,而每個Schema又包含多個數據庫對象(表、視圖、字段等),反過來講一個數據庫對象必然屬于一個Schema,而該Schema又必然屬于一個Catalog,這樣我們就可以得到該數據庫對象的完全限定名稱從而解決命名沖突的問題了;例如數據庫對象表的完全限定名稱就可以表示為:Catalog名稱.Schema名稱.表名稱。這里還有一點需要注意的是,SQL標準并不要求每個數據庫對象的完全限定名稱是唯一的,就象域名一樣,如果喜歡的話,每個IP地址都可以擁有多個域名。
從實現的角度來看,各種數據庫系統對Catalog和Schema的支持和實現方式千差萬別,針對具體問題需要參考具體的產品說明書,比較簡單而常用的實現方式是使用數據庫名作為Catalog名,使用用戶名作為Schema名,具體可參見下表:
最后一點需要注意的是Schema這個單詞,它在SQL環境下的含義與其在數據建模領域中的含義是完全不同的。在SQL環境下,Schema是一組相關的數據庫對象的集合,Schema的名字為該組對象定義了一個命名空間,而在數據建模領域,Schema(模式)表示的是用形式語言描述的數據庫的結構;簡單來說,可以這樣理解,數據建模所講的Schema<也就是元數據>保存在SQL環境下相應Catalog中一個Schema<名叫DEFINITION_SCHEMA>下的表中,同時可以通過查詢該Catalog中的另一個Schema<名叫INFORMATION_SCHEMA>下的視圖而獲取,具體細節不再贅述。
?