DBA眼中的CLR
SQL Server 2005引入CLR之後,開發者們熱情地接受了它。
CLR作爲一個強有力的工具,開發者可在數據庫中利用它調用其它面嚮對象語言編寫而成的功能。
從DBA的視角來看,CLR的引入淡化了編譯型代碼與數據庫代碼的區別。它引發了在部署、管理CLR代碼以及安全性上,開發者和DBA的角色問題。
在某種程度上,它也淡化了在多層架構的系統中。業務邏輯層和數據访問層的區間。
對許多組織而言。實現CLR须要決策有關開發過程和它們涉及到的角色。假设你準備執行CLR,你须要足夠多的非技術細節信息來印證這些決定。
最後。我將指出怎样實現CLR,討論CLR代碼的利弊。以及CLR技術給SQL Server管理和安全方面帶來的影響。我也將描写叙述哪些情況適合用CLR,而哪些情況可能不適合。
創建與部署CLR
CLR是一個程序模型,它允許開發者用面嚮對象語言來寫編寫代碼,然後像T-SQL存儲過程、函數或觸發器一樣去使用它。一般創建過程例如以下:
1、創建VSproject,代碼能够用C#/VB.Net編寫;
2、代碼被編譯後,直接從VS部署到目標數據庫。編譯後會產生一個DLL文件,DLL是一個包括編譯後代碼的可運行的文件。部署後,將會在sys.assemblies視圖和其它相關視圖中插入對應程序集信息。
3、通過對程序集運用EXTERNAL NAME選項。一個或多個T-SQL對象將在數據爲中被創建。這些對象對稱爲原型,一個原型能被定義爲存儲過程,函數。用戶自定義聚集函數或用戶自定義類型。
原型中不包括代碼。它仅仅是一個簡單的可被其它數據庫代碼調用的入口。被調用時。DLL中編譯後的代碼將會運行。
通常,當你從VS編譯和部署時,上述全部步驟都會被執行,但你也能够手動分開執行每一步。
現代的面嚮對象語言有一些對T-SQL來說是非常困難甚至無法實現的功能。CLR則提供了一種在數據庫中運用這些語言豐富特性的方式。對於計算或迭代性的操作。CLR通常提供比T-SQL更優的性能。CLR代碼和SQL Server在同一個內存上下文中運行,所以它運行得非常有效率。
CLR代碼是被託管的代碼,這意味着它在『CLR運行時』中運行時,能够確保不會出現代碼運行時使服務器不穩定的情況。盡管這是好事,但不论什么形式的虛擬化都會有一定程序的開銷,CLR假设運用不當還是會影響性能的。盡管編譯後的代碼在SQL內存空間中會運行得非常有效率。但T-SQL仍然是繁重工作的最好選擇。假设要访問和返回大批量的數據,CLR並不是一個好的選擇。
總之中的一个句話,T-SQL處理集合類操作更加有效率,而CLR對迭代、過程、計算類操作更加在行。當然也會有例外的時候。
管理CLR
有時DBA與CLR打的第一個交道就是有人提議在服務器上啟用CLR。雖然啟用CLR仅仅是在服務的選項中啟用CLR配置項這麼簡單。但在啟動它之前你须要考慮非常多問題。
將腳本部署到數據庫是DBA的傳統職責,DBA同時也要保證腳本正常工作并且不影響性能或引發服務器上的其它問題。
然而,CLR代碼通常是從VS開發環境中直接部署到數據庫中的,而DBA一般不使用VS,這似乎意味著開發人員比DBA更適合去部署CLR代碼。
開發人員能够編寫編譯過後的代碼在SQL Server中像SQL代碼一樣運行。DBA或許會對此感覺不爽,但DBA仍然能够控制誰能够加載CLR程序集,在什麼安全級別下運行CLR功能。
CLR安全性
默認的。仅仅有sysadmin、db_ower、ddl_admin角色的用戶有權限去運行程序集相關的DDL語句。這個權限能够賦給其它角色和用戶。另外,例如以下三種權限集能够讓你設置程序集本身的三種安全級別:
SAFE。此安全級別仅仅允許访問本地數據和內部計算。
對系統資源,比方文件、網絡、環境變量或者註册表的访問是禁止的。不论什么有創建程序集權限的用戶都能够創建一個SAFE級別的程序集。假设CREATE ASSEMBLY語句沒有顯示指定安全級別,SAFE將是默認的級別。
EXTERNAL ACCESS。
此安全級別允許程序集访問外部資源。擁有EXTERNAL ACCESS權限的用戶才干够創建此安全級別的信息集。
UNSAFE。
在將程序集設為UNSAFE時請三思,此級別的程序集在SQL Server內外都擁有不受約束的访問權限。在UNSAFE程序集裏的代碼也可能是不受管理的代碼,意味著它有讓服務器不穩定的可能。
僅sysadmins用戶組的用戶能够登陸UNSAFE的程序集。
默認的,CLR代碼都是在SQL SERVER服務帳號的安全上下文運行。假设你要访問SQL Server之外的資源,這就會有問題,最好的做法是不超過服務帳號的權限。可是CLR代碼能够通過模擬其它Windows帳號來運行。
UNSAFE和EXTERNAL ACCESS安全級別的程序集有這種能力。能够創建這種程序集的人必須是深受公司信任的。
理解CLR元數據
在一個啟用了CLR選項的環境中。DBA應該對例如以下5個包括了元數據信息的系統視圖非常熟悉:
sys.assembiles. 此視圖每行記錄對應一個程序集。
它包括了程序集的一些屬性。比方名稱、安全級別和創建日期。
sys.assembly_files. 對數據庫中每一個程序集。這個視圖都包括了一行信息說明其源文件、DLL文件。
sys.assembly_modules. 一個程序集可能包括多個類。比方存儲過程和函數。程序集裏的類可能包括多個實現不同功能的代碼模塊。這個視圖將各自獨立的代碼模塊ID與引用它們的數據庫對象ID關聯在一起了。例如以下查詢能够查出每個CLR數據庫對象引用的程序集的類和方法:
SELECT OBJECT_NAME(m.object_id) AS db_object
,a.name AS assembly
,m.assembly_class
,m.assembly_method
FROM sys.assembly_modules m
INNER JOIN sys.assemblies a ON a.assembly_id = m.assembly_id
sys.assembly_references.程序集之間的相互引用依賴關係。
sys.module_assembly_usages將程序集的ID與引用它們的數據庫對象ID,關係起來了。
SELECT OBJECT_NAME(object_id) AS db_object
,a.name AS assembly
FROM sys.module_assembly_usages u
INNER JOIN sys.assemblies a ON a.assembly_id = u.assembly_id
移除CLR程序集
VS能够非常方便創建和部署CLR程序集到SQL Server中,但並沒有同樣方便的工具去卸載它們。你必須有順序地手動將它們移動。
在移除某程序集之前能够通過查看依賴項先移動那些引用此程序集的T-Sql對象。能够Sp_Depends或在對象資源管理器中右鍵查看。
更好的改變
純T-SQL的數據庫編程時代正在發生變化。CLR正是這一跡象的样例。盡管有人會有點排斥。但正是變化讓DBA生涯變得有趣。CLR真正突破了T-SQL在某些方面的限制。
兩種模式的混合編程能力是一個強大的工具,DBA和開發者都應該掌握它們。
附经常使用查詢
-- Assembly Query
SELECT * FROM sys.assembly_modules;
SELECT * FROM sys.assemblies;
SELECT * FROM sys.assembly_files;
-- CLR Object In Database
SELECT * FROM sys.objects WHERE type_desc LIKE 'CLR%';
-- 哪些系统对象引用了CLR程序集
SELECT OBJECT_NAME(object_id) AS [Object_Name],b.Name AS Assembly_Name
FROM sys.module_assembly_usages a
INNER JOIN sys.assemblies b ON a.assembly_id = b.assembly_id;