SQL SERVER 中的Schema詳解

以往 SQL Server 內的對象命名是「服務器.數據庫.用戶名.對象」,但新版的對象命名改成「服務器.數據庫.Schema.對象」。這讓你規劃數據庫對象命名時更有彈性。 程序員

   架構是造成單個命名空間的數據庫實體的集合。命名空間是一個集合,其中每一個元素的名稱都是惟一的。 sql

   雖然 SQL Server 2000 包含 CREATE SCHEMA 語句,但實際上並不會像上面所定義的那樣建立架構。在 SQL Server 2000 中,數據庫用戶和架構是隱式鏈接在一塊兒的。每一個數據庫用戶都是與該用戶同名的架構的全部者。對象的全部者在功能上與包含它的架構全部者相同。於是,SQL Server 2000 中的徹底限定名稱的「架構」也是數據庫中的用戶。所以,從 SQL Server 2000 數據庫中刪除用戶以前,管理員須要刪除該用戶所擁有的全部對象或更改這些對象的全部者。以包含此對象的 SQL Server 2000 數據庫爲例: 數據庫

   accounting.ap.george.reconciliation windows

   此對象的全部者爲用戶「george」。若是管理員須要刪除用戶「george」,則必須先刪除此對象或更改此對象的全部者。在後一種狀況下,能夠按以下方式將其重命名: 安全

   accounting.ap.sandra.reconciliation 服務器

   轉讓對象的全部權也會更改其徹底限定名稱。引用 accounting.ap.george.reconciliation 的任何代碼必須通過更新以反映對名稱所作的更改。 架構

   在 SQL Server 2005 中,架構獨立於建立它們的數據庫用戶而存在。能夠在不更改架構名稱的狀況下轉讓架構的全部權。而且能夠在架構中建立具備用戶友好名稱的對象,明確指示對象的功能。例如,除了 accounting.ap.sandra.reconciliation 外,您還能夠建立名爲 accounting.ap.invoice.reconciliation 的架構。由於「invoice」不是用戶,因此從數據庫中刪除用戶後,無需更改此名稱。這就簡化了數據庫管理員和開發人員的工做。 測試

   用戶架構分離的好處

   將架構與數據庫用戶分離對管理員和開發人員而言有下列好處: 網站

   多個用戶能夠經過角色成員身份或 Windows 組成員身份擁有一個架構。這擴展了容許角色和組擁有對象的用戶熟悉的功能。 

   極大地簡化了刪除數據庫用戶的操做。 

   刪除數據庫用戶不須要重命名該用戶架構所包含的對象。於是,在刪除建立架構所含對象的用戶後,再也不須要修改和測試顯式引用這些對象的應用程序。 

   多個用戶能夠共享一個默認架構以進行統一名稱解析。 

   開發人員經過共享默認架構能夠將共享對象存儲在爲特定應用程序專門建立的架構中,而不是 DBO 架構中。 

   能夠用比早期版本中的粒度更大的粒度管理架構和架構包含的對象的權限。

   徹底限定的對象名稱如今包含四部分:server.database.schema.object。 

   用戶與架構(schema)分開,讓數據庫內各對象?再綁在某個用戶帳號上,能夠解決以前版本「用戶離開公司"問題,也就是在擁有該對象的用戶離開公司,或離開該職務時,?必要大費周章地?改該用戶全部的對象屬於新的用戶全部。另外,也可以讓 DBA 在安裝某個套裝軟件時,設置該套裝軟件所用的數據庫對象都屬於某個特定的架構,容?區別。也就是說,在單一數據庫內,?同部門或目的的對象,能夠經過架構區分?同的對象命名原則與權限。 spa

   默認架構

   SQL Server 2005 還引入了「默認架構」的概念,用於解析未使用其徹底限定名稱引用的對象的名稱。在 SQL Server 2000 中,首先檢查的是調用數據庫用戶所擁有的架構,而後是 DBO 擁有的架構。在 SQL Server 2005 中,每一個用戶都有一個默認架構,用於指定服務器在解析對象的名稱時將要搜索的第一個架構。可使用 CREATE USER 和 ALTER USER 的 DEFAULT_SCHEMA 選項設置和更改默認架構。若是未定義 DEFAULT_SCHEMA,則數據庫用戶將把 DBO 做爲其默認架構。

   SQL Server 2005 Database Engine 管理着能夠經過權限進行保護的實體的分層集合。這些實體稱爲「安全對象」。在安全對象中,最突出的是服務器和數據庫,但能夠在更細的級別上設置離散權限。SQL Server 經過驗證主體是否已得到適當的權限來控制主體對安全對象執行的操做。

我相信不少人接觸這些概念的時候一頭霧水。要把這些概念理清楚真不是件容易的事,哪像原始社會,只要能分清楚什麼能吃什麼不能吃就好了。

可是我始終堅信,每個概念的產生必然是由於碰到了沒法解決的問題。換句話說,若是沒有它,必然會致使某些問題難以解決。因此我想從這個角度切入,但願能把這幾個複雜而曖昧的多角關係從最實用的角度來闡述清楚。

在問題的最初,咱們假定的數據庫什麼都沒有。

數據庫對象。首先,數據庫對象是比較容易懂的。全部的表,視圖,存儲過程,觸發器都稱爲數據庫對象。

咱們能夠拿一個網站來作類比。一個網站包含不少的網頁,圖片,腳本文件,咱們姑且稱它爲網站對象。

顯然,咱們不可能把全部的網站對象都放到一個文件夾下面,一樣道理,數據庫對象也不可能象煮餃子同樣就在數據庫裏這麼一鍋出。對於網站,咱們一般會把不一樣模塊的文件放在不一樣的子文件夾下,那麼誰是存放數據庫對象的文件夾呢?答案就是:架構(Schema).

架構(Schema)。微軟的官方說明(MSDN): "數據庫架構是一個獨立於數據庫用戶的非重複命名空間,您能夠將架構視爲對象的容器",詳細參考http://technet.microsoft.com/zh-cn/library/ms190387.aspx.咱們知道,在JAVA中,命名空間名其實就是文件夾名。所以咱們很是明確一點:一個對象只能屬於一個架構,就像一個文件只能存放於一個文件夾中同樣。與文件夾不一樣的是,架構是不能嵌套的,如此而已。所以,咱們要訪問一個數據庫對象的時候,一般應該是引用它的全名"架構名. 對象名",這點很是相似C#。

問:爲何有的時候寫select * from tablename也能夠執行呢?

答:這是由於default schema.當只寫tablename時,Sql Server會自動加上當前登陸用戶的default schema。

 

若是此表不屬於當前登陸用戶的default schema,將會提示無效的對象名。

 

加上shcema之後成功。

 

不過咱們也能夠更改當前用戶的default schema,這時就能夠不用加前綴了。

Code

ALTER USER dbo WITH DEFAULT_SCHEMA =emdbuser;

固然,咱們也能夠改變此表的schema,至關於把這個表放到另外一個文件夾,從emdbuser放到dbo中。

Code

alter schema dbo TRANSFER emdbuser.Borrower

以上兩種做法在真實項目中都不該該做爲解決方案,由於它改變了原來的設置。咱們最但願的是,即便咱們以dbo登錄,咱們也能夠假裝成emdbuser來操做數據庫對象,假裝完了還能切換回來。在Sql Server中,恰好有這樣的語句實現這個功能。

Code

EXECUTE AS USER = 'emdbuser';

這種機制被稱爲「上下文切換」,操做完之後,能夠實用REVERT命令切換回來。(.NET中也有相似的機制,它們有共同的一個名稱叫作Impersonate,角色扮演。)

詳細解釋參照MSDNhttp://msdn.microsoft.com/zh-cn/library/bb153640(SQL.90).aspx

問:如何根據表名獲取一個表的Schema呢?

答:能夠參照如下SQL語句從sys.objects視圖和sys.schemas視圖中獲取。

Code

select sys.objects.name,
sys.schemas.name
from sys.objects,
sys.schemas
where sys.objects.type='U'
and sys.objects.schema_id=sys.schemas.schema_id

結論:架構就是數據庫對象的容器。數據庫對象是飲料,架構就是杯子,誰拿杯子喝水呢?固然是用戶,那麼是否是一個用戶只能用一個杯子,一個杯子是否是從一而終,只能給一我的用呢?。請看第二節

 

 

 

在第一節中,咱們瞭解了架構的意義。在第二節的開始,咱們暫時忘記架構這個東西。咱們假設咱們的數據庫只有數據庫對象。

李老闆開了一個小公司,公司有個倉庫,堆放了一些貨物,因爲倉庫小,爲了節約成本,這個倉庫根本沒有鎖。只要知道倉庫在哪裏,就能夠去取貨。這種狀況對應數據庫來講,就是隻要我知道數據庫名和表名,我就能夠對它進行操做。這對程序員來講固然是最方便了。這就是數據庫的第一階段:無權限管理階段。假如你們用過Win3.X,那它們基本就是無權限管理階段。這下小偷就爽翻了。

 

最近倉庫裏的東西總是不知去向。李老闆才明白,就算是員工都是自覺的,可是別的人也能夠拿走裏面的貨物,怎麼辦呢?老闆一咬牙,花一百塊錢買了一把鎖!而且只給少數幾我的配鑰匙。這下東西被別的公司的人拿走的狀況基本杜絕了。對於數據庫來講,至關於把人分紅了兩種,一種受權用戶,一種未受權用戶。這時,數據庫就有了用戶的概念,可是它只有一個用戶,就是有鑰匙的人,它只對有鑰匙的人開放。這就是數據庫權限管理的第二階段:上鎖階段或者單用戶管理階段。

 

好景不長,老闆發現倉庫的東西仍是常常少。明明都是有鑰匙的人才能進去呀。可是,誰拿了多少,根本沒辦法查出來。老闆猜想緣由有二:一,有些人拿了不應拿的東西。二,有些人偷偷的去配了鑰匙。老闆一咬牙,沒收全部的鑰匙。花800塊一個月僱個倉庫管理員,每一個進倉庫拿東西的人都要登記。李老闆還給給倉庫管理員一個清單,誰能夠拿什麼東西,清單以下:

 

 

這時的管理上了一個新臺階,稱爲用戶-權限管理階段。公司再也沒發生丟東西的現象。老闆很是得意本身英明的決定。這就很是相似windows如今的用戶權限管理了。

 

也許有人細心的發現,你說的不對,windows權限管理中有角色呀!沒錯,爲何要有角色呢?沒有角色不是照樣不丟東西嗎?這個問題稍後再談。

話說過了一年,李老闆的生意越作越大,倉庫裏的東西也愈來愈多,最近張三反應,去倉庫取貨總是要排隊,並且常常要等好久才能取到貨,李老闆心想,取貨的人一共就這幾我的,還要排隊,豈有此理!把倉庫保管員叫過來!保管員早有準備,遞給李老闆一份最新的清單:

 

 

每次來一我的取貨,保管員都要根據這張清單對一千個貨物,幸好取貨的人少,若是再多幾我的的話,估計就要在倉庫門口打架了。李老闆又開始琢磨了。如今東西是不會丟了,可是每次取貨慢成這樣,等我貨再多到一萬種,我這生意還能作嗎?該怎麼才能提升倉庫管理員的效率呢?這時倉庫管理員早看出李老闆的心思,色咪咪看着李老闆着說:「老闆,再招一個管理員吧,我老婆恰好生完孩子在家裏待業。。。」。李老闆一聽就火了:你當招人不用花錢啊!有了!我買5個貨架就搞定了!過兩天我告訴你新的管理辦法,你老婆仍是在家多休息幾天吧。

過了幾天,老闆把5個貨架採購回來,放進倉庫,而後給管理員一份管理手冊。新的管理手冊以下:

 

 

第四頁,第五頁省略

每次貨物入庫的時候,根據貨架貨物清單放到相應的貨架上,而後貼上標籤。出庫的時候哦只要看貨架號碼就能夠啦。

看到這裏,也許有人恍然大悟,這不就是第一節講的「架構Schema」嗎?沒錯,如今咱們終於知道,架構概念的引入就是爲了解決數據庫對象太多很差管理的缺點。到如今爲止,咱們的數據庫管理就變成了用戶-架構-數據庫對象的模式了。

在sql server2000中,用戶和架構是不分離的,到了2005才分離。其實2000中的用戶和架構概念就是給張3、李四分配固定的貨架。這是一種更簡單的管理方法

相關文章
相關標籤/搜索