數據庫中的Schema和Database的區別
在mysql中創建一個Schema和創建一個Database的效果好像是一樣的,但是在sqlserver和orcal數據庫中效果又是不同的,目前我只能理解為在mysql中schema<==>database;
數據庫中的user和schema的關系:
假如我們想了解數據庫中的user和schema的關系,首先必須要清楚數據庫中的user和schema的概念。
在sqlserver2000中,由于架構的原因,user和schema總有一層隱含的關系,讓我們很少意識到其實user和schema是兩種完全不同的概念,不過在sqlserver2005中這種架構被打破了,user和schema也被分開了。
首先來做一個比喻,什么是database,schema,table,列,行,user?可以把database看作是一個大的倉庫,倉庫分了很多很多的房間,schema就是其中的房間,一個schema代表一個房間,table可以看作是每個schema中的床,table(床)就被放入每個房間中,不能放置在房間之外,那豈不是晚上睡覺無家可歸啊。然后床上可以放置很多物品,好比table可以放置很多列和行一樣,數據庫中存儲數據的基本單元是table,現實中每個倉庫放置物品的基本單位就是床,user就是每個schema的主人,(所以schema包含的object,而不是user),其實user是對應與數據庫的(即user是每個對應數據庫的主人),既然有操作數據庫的(倉庫)的權利,就肯定有操作數據庫中每個schema(房間)的權利,就是說每個數據庫映射的user有每個schema(房間)的鑰匙,換句話說,如果它是某個倉庫的主人,那么這個倉庫的使用權和倉庫中的所有東西都是他的(包括房間),他有完全的操作權,可以扔掉不用的東西從每個房間,也可以放置一些有用的東西到某一個房間,這個現實中的相似,我還可以給user分配具體的權限,也就是他到某一房間能做些什么,是只能看(read-only),還是可以像主人一樣有所有的控制權(r/w),這個就要看這個user所對應的角色role了。
在sqlserver2000中,假如我們在某一數據庫中創建了用戶Bosco,那么此時后臺也為我們默認的創建了schema【Bosco】,schema的名字和user的名字相同,這也是我們分不清用戶和schema的原因。
在sqlserver2005中,為了向后兼容,當你用sp_adduser存儲過程創建一個用戶的時候,sqlserver2005同時也創建了一個和用戶名相同的schema,然而這個存儲過程是為了向后兼容才保留的,我們應該逐漸熟悉用新的DDL語言create user和create schema來操作數據庫,在sqlserver2005中,當我們用create user創建數據庫用戶時,我們可以用該用戶指定一個已經存在的schema作為默認的schema,如果我們不指定,則該用戶所默認的schema即為dbo schema,dbo房間(schema)好比一個大的公共房間,在當前登錄用戶沒有默認schema的前提下,如果你在大倉庫中進行一些操作,比如create table,如果沒有制定特定的房間(schema),那么你的物品就只好放進公共的dbo房間(schema)了。但是如果當前登錄用戶有默認的schema,那么所做的一切操作都是在默認的schema上進行(比如當前登錄用戶為login1,該用戶的默認schema為login1,那么所做的所以操作都是在這個login1默認schema上進行的。實驗已經證明的確如此)。估計此時你會有一點暈,剛才說dbo是一個schema,但是你可以在數據庫中查看到,dbo同事也是一個user,暈了吧。
在sqlserver2005中創建一個數據庫的時候,會有一些schema包括進去,被包括進去的schema有:dbo,INFORMATION_SCHEMA,guest,sys等等(還有一些角色schema)。
在上文中已經提到了,在sqlserver2005中當用存儲過程sp_adduser創建一個user時,同時sqlserver2005也為我們創建了一個默認的和用戶名相同的schema,這個問題出來了,當我們create table a時,如果沒有特定的schema做前綴,這個a表創建在了哪個schema上,即進入了哪個房間?答案是:
1.如果當前操作數據庫的用戶(可以用select current_user查出來)有默認的schema(在創建用的時候指定了),那么表a被創建在了默認的schema上。
2.如果當前操作數據庫的用戶沒有默認的schema(即在創建user的時候默認為空),但是有一個和用戶名同名的schema,那么表a照樣被創建在了dbo schema上,即使有一個和用戶名同名的schema存在,由于它不是該用戶默認的schema,所以創建表的時候是不會考慮的,當作一般的schema來處理,別看名字相同,可是沒有任何關系哦。
3.如果在創建表a時候指定了特定的schema做前綴,則表a被創建在了指定的schema上(有權限嗎?)
現在問題又出來了,在當前操作數據庫的用戶(用select current_user可以查看到,再次強調)沒有默認schema的前提下,當我們用create table a語句時,a表會去尋找dbo schema,并試圖創建在dbo schema上,但是如果創建a表的用戶只有對dbo schema的只讀權限,而沒有寫的權限呢?這個時候a表既不是建立不成功,這個就是會提到的login,user,role和schema四者的關系,在這里,為了避免混淆和提高操作數據庫的速度(在少量數據范圍內,對我們肉眼來說幾乎看不到差異),我們最好每次在操作數據庫對象的時候都顯式地指定特定的Schema最為前綴。
現在如果登錄的用戶為Sue,該用戶有一個默認Schema也為Sue,那么如果現在有一條查詢語句為Select * from mytable, 那么搜尋每個房間(Schema)的順序是怎樣的呢?順序如下:
1. 首先搜尋sys.mytable (Sys Schema)
2. 然后搜尋Sue.mytable (Default Schema)
3. 最后搜尋 dbo.mytable (Dbo Schema)
執行的順序大家既然清楚了,那么以后在查詢數據庫表中的數據時,最好指定特定的Schema前綴,這樣子,數據庫就不用去掃描Sys Schema了,當然可以提高查詢的速度了。
另外需要提示一下的是,每個數據庫在創建后,有4個Schema是必須的(刪都刪不掉),這4個Schema為:dbo,guest,sys和INFORMATION_SCHEMA,其余的Schema都可以刪除。
posted on 2013-12-18 11:02 順其自然EVO 閱讀(926) 評論(0) 編輯 收藏 所屬分類: 數據庫