SQL Server 2005 引入了架構的概念,而不是以前版本中的對象所有者。本文将解釋兩者之間的差別,并希望消除對架構仍然存在的一些困惑。
對象所有者(Object Owners)
為了了解所有者和架構之間的差別,讓我們花點時間回顧一下對象所有權。在 SQL Server 2000 或更早的版本中建立對象時,該對象必須擁有所有者。大多數情況下,所有者是“dbo”,也稱為資料庫所有者。對象可能屬于資料庫中的任何使用者帳戶。确定所有者的方法是檢視完全限定對象名稱。當您檢視表清單時,可以使用 SQL Server Enterprise Manager 或 Management Studio 檢視完全限定對象名稱。例如,dbo 擁有的名為orders 的表的名稱是 dbo.orders。如果表的所有權轉移到使用者 abc,那麼表現在将被命名為 abc.orders。
對象如何獲得它的所有者?這取決于建立它的使用者。db_owner 角色的人也可以建立資料庫中任何使用者擁有的對象。預設情況下,建立對象的使用者帳戶(帳戶必須具有 CREATE TABLE 權限)也将擁有該對象。隻有具有 db_owner 角色的使用者帳戶才能建立屬于 dbo 的對象。即使這樣,在某些情況下,所有者最終将是實際的使用者帳戶,而不是 dbo。
使用 dbo 作為所有資料庫對象的所有者可以簡化對象的管理。在資料庫中始終有一個 dbo 使用者。隻要該使用者擁有适當的權限,資料庫中的使用者将能夠通路 dbo 擁有的任何對象,而無需指定所有者。如果對象屬于 dbo 以外的帳戶,則在删除原始帳戶時,必須将該帳戶的所有權轉移給其他使用者。例如,如果一個名為“ted”的非 dbo 資料庫使用者建立了 sales 表,那麼它将被稱為 ted.sales。為了讓 Ted 以外的使用者看到這個表,它必須由完全限定名引用。如果 Ted 離開了公司或部門,并且必須從資料庫中删除他的帳戶,那麼必須使用 sp_changeobjectowner 存儲過程将表的所有權轉移到另一個使用者帳戶,然後才能删除 Ted 的帳戶。
如果在應用程式中使用過表或在存儲過程等任何定義中引用過表,那麼更改所有者将破壞所有代碼。如果 dbo 從一開始就擁有這個表,那麼删除Ted 的帳戶就沒有問題。代碼不需要使用完全限定名,這樣做會略微提高性能,這被認為是最佳實踐。
架構(Schemas)
我喜歡把架構看作是組織對象的容器。如果您看一下 AdventureWorks 示例資料庫(如下圖),您将看到這些表是按部門或功能組織的,比如 “Sales” 或 “Production”。這看起來與舊的所有者概念相似,但有很多優點。首先,由于對象沒有綁定到任何使用者帳戶,是以在删除帳戶時,您不必擔心更改對象的所有者。另一個優點是架構可以用于簡化對表和其他對象的權限管理。架構有一個所有者,但所有者沒有綁定到名稱。是以,如果一個帳戶擁有一個架構,并且必須從資料庫中删除該帳戶,則可以在不破壞任何代碼的情況下更改架構的所有者。如果不希望将資料庫對象組織成架構,可以使用 dbo 架構。

假設 Dev 部門中的員工是同一個網絡安全組 DevEmp 的成員。每個部門的經理都是另一個組 DevManagers 的成員。我們建立了一個名為 Devs 的架構,Devs 架構中包含了許多表、視圖和存儲過程。為了控制對對象的通路,我們可以将 DevEmp 和 DevManagers 網絡組添加到 SQL Server 和資料庫中。因為我們關注的是對表的通路控制,是以 DevEmp 組被授予了 Dev 架構中所有存儲過程的執行權限。DevManagers 組還被授予了對所有表和視圖的選擇權限。這樣做的好處是,隻要在 Devs 架構中建立新的存儲過程、表或視圖,您就不再需要記住授予權限。
要向架構中的所有存儲過程授予執行權限,步驟如下:
- 使用 SSMS 連接配接執行個體,資料庫—安全性—架構;
- 右鍵架構名(如Person)并選擇屬性;
- 選擇權限頁面,單擊搜尋選擇資料庫使用者或角色;
- 一旦選擇了使用者或角色,底部将出現權限清單;
- 若要向所有存儲過程授予執行權限,請選中“execute”;
這樣,該使用者就擁有了該架構存儲過程的執行權限了。該設定有類似如 db_datareader 這樣的角色概念,不過除了表外沒有其他相應的角色。對于給使用者設定存儲過程執行權限,隻能像上面這樣設定了。
對于架構的設定,若要變更比較麻煩。是以架構的設定一定在設計的時候考慮好,設計好了之後基本就不再更改了。通常使用最佳實踐設計,預設使用架構 dbo 就好。架構的應用,在權限管理方面非常靈活,但也會增加維護複雜度,需要對架構足夠了解。