1.視圖
(1).什麼是視圖?
視圖(View)做爲一種數據庫對象,爲用戶提供了一個能夠檢索數據表中的數據方式。用戶經過視圖來瀏覽數據表中感興趣的部分或所有數據,而數據的物理存儲位置仍然在表中。
視圖是一個虛擬表,並不表明任何物理數據,只是用來查看數據的窗口而已。視圖並非以一組數據的形式存儲在數據庫中,數據庫中只存儲視圖的定義,而不存儲視圖對應的數據,這些數據仍存儲在導出視圖的基本表中。當基本表中的數據發生變化時,從視圖中查詢出來的數據也隨之改變。
視圖中的數據行和列都是來自於基本表,是在視圖被引用時動態生成的。使用視圖能夠集中、簡化和制定用戶的數據庫顯示,用戶能夠經過視圖來訪問數據,而沒必要直接去訪問該視圖的基本表。
視圖由視圖名和視圖定義兩個部分組成。視圖是從一個或多個表導出來的表,它其實是一個查詢結果,視圖的名字和視圖對應的查詢存儲在數據字典中。html
(2).視圖的優缺點?
<1>.視圖的優勢
A.數據安全性。
對不一樣的用戶定義不一樣的視圖,使用戶只能看到與本身有關的數據。數據庫受權命令可使每一個用戶對數據庫的檢索限制到特定的數據庫對象上,但不能受權到數據庫特定行和特定的列上。經過視圖,用戶能夠被限制在數據的不一樣子集上。
B.查詢簡單化。
爲複雜的查詢創建一個視圖,用戶沒必要輸入複雜的查詢語句,只需針對此視圖作簡單的查詢便可。那些被常用的查詢能夠被定義爲視圖,從而使用戶沒必要爲之後的操做每次都指定所有的條件。
C.邏輯數據獨立性。
視圖可使應用程序和數據庫表在必定程度上獨立。若是沒有視圖,應用必定是創建在表上的。有了視圖以後,程序能夠創建在視圖之上,從而程序與數據庫表被視圖分割開來。
對於視圖的操做,例如,查詢只依賴於視圖的定義,當構成視圖的基本表須要修改時,只須要修改視圖定義中的子查詢部分,而基於視圖的查詢不用改變。數據庫
<2>.視圖的缺點
A.性能。
SQL Server必須把視圖的查詢轉化成對基本表的查詢,若是這個視圖是由一個複雜的多表查詢所定義,那麼,即便是視圖的一個簡單查詢,SQL Server也把它變成一個複雜的結合體,須要花費必定的時間。
B.修改限制。
當用戶試圖修改視圖的某些行時,SQL Server必須把它轉化爲對基本表的某些行的修改。事實上,當從視圖中插入或者刪除時,狀況也是這樣。對於簡單視圖來講,這是很方便的,可是,對於比較複雜的視圖,多是不可修改的,這些視圖有以下特徵:
a.有UNIQUE等集合操做符的視圖。
b.有GROUP BY子句的視圖。
c.有諸如AVG\SUM\MAX等聚合函數的視圖。
d.使用DISTINCT關鍵字的視圖。
e.鏈接表的視圖(其中有些例外)
(3).建立視圖的限制:
在建立視圖時,還要注意試圖必須知足如下幾點限制:
<1>.不能將規則或者DEFAULT定義關聯於視圖。
<2>.定義視圖的查詢中不能含有ORDER BY\COMPURER\COMPUTER BY 子句和INTO關鍵字
<3>.若是視圖中某一列是一個算術表達式、構造函數或者常數,並且視圖中兩個或者更多的不一樣列擁有一個相同的名字(這種狀況一般是由於在視圖的定義中有一個鏈接,並且這兩個或者多個來自不一樣表的列擁有相同的名字),此時,用戶須要爲視圖的每一列指定列的名稱。express
參考博客:
《使用SQL Server視圖的優缺點》編程
2.索引
(1).什麼是索引?
索引是以表列爲基礎的數據庫對象,它保存着表中排序的索引列,而且記錄了索引列在數據表中的物理存儲位置,實現了表中數據的邏輯排序,其主要目的是提升SQL Server系統的性能,加快數據的查詢速度和減小系統的響應時間。索引經過記錄表中的關鍵值指向表中的記錄,這樣數據庫引擎就不用掃描整個表而定位到相關的記錄。相反,若是沒有索引,則會致使SQL Server搜索表中的全部記錄,以獲取匹配結果。
索引除了能夠提升查詢表內數據的速度之外,還可使表和表之間的鏈接速度加快。例如,在實現數據參照完整性時,能夠將表的外鍵製做爲索引,這樣將加速表與表之間的鏈接。安全
(2).索引的分類
有3種索引類型:彙集索引、非彙集索引和惟一索引。若是表中存在彙集索引,則非彙集索引使用匯集索引來加快數據查詢。
<1>.彙集索引
彙集索引會對錶和視圖進行物理排序,因此這種索引對查詢很是有效,在表和視圖中只能有一個彙集索引。當創建主鍵約束時,若是表中沒有彙集索引,SQL Server會用主鍵列做爲彙集索引鍵。能夠在表的任何列或列的組合上創建索引,實際應用中通常定義成主鍵約束的列創建彙集索引。
<2>.非彙集索引
非彙集索引不會對錶和視圖進行物理排序。若是表中不存在彙集索引,則表示未排序的。在表或視圖中,最多能夠創建250個非彙集索引,或者249個非彙集索引和1個彙集索引。
<3>.惟一索引
惟一索引不容許兩行具備相同的索引值。只要列中數據是惟一的,就可在同一個表上建立一個惟一的彙集索引。若是必須實施惟一性以確保數據的完整性,則應在列上建立UNIQUE或PRIMARY KEY約束,而不要建立惟一索引。性能優化
(3).使用索引的代價
雖然索引有不少優勢,但索引的存在也讓系統付出了必定的代價。建立索引和維護索引都會消耗時間,當對錶中的數據進行增長、刪除和修改操做時,索引就要進行維護,不然索引的做用就會降低;另外,每一個索引都會佔用必定的物理空間,若是佔用的物理空間過多,就會影響到整個SQL Server系統的性能。服務器
(4).創建索引的原則
建立索引雖然能夠提升查詢速度,可是它是犧牲必定的系統性能。所以,在建立時,哪些列適合建立索引,哪些列不適合建立索引,須要進行判斷,具體如下原則:
<1>.有主鍵的數據列要創建索引。由於主鍵能夠加速定位到表中的某一行。
<2>.有外鍵的數據列要創建索引。外鍵列一般用於表與表之間的鏈接,在其上建立索引能夠加快表間的鏈接。
<3>.對於常常查詢的數據列最好創建索引。
A.對於須要在指定範圍內快速或頻繁查詢的數據列,由於索引已經排序,其指定的範圍是連續的,查詢能夠利用索引的排序,加快查詢的時間。
B.常常用在WHERE子句中的數據列,將索引創建在WHERE子句的集合過程當中,對於須要加速或頻繁檢索的數據列,可讓這些常常參與查詢的數據列按照索引的排序進行查詢,加快查詢的時間。
<4>.對於那些查詢中不多涉及的列、重複值比較多的列不要創建索引。
例如,在查詢中不多使用的列,有無索引並不能提升查詢的速度,相反增長了系統維護時間和消耗了系統空間。
<5>.對於定義爲text、image和bit數據類型的列不要創建索引。由於這些數據類型的數據列的數據量要麼很大、要麼很小,不利於使用索引。網絡
參考博客:
《SQLServer索引調優實踐》
《SQL Server索引維護指導(1)》
《詳細講解SQL Server索引的性能問題》併發
3.存儲過程
(1).什麼是存儲過程?
當開發一個應用程序時,爲了易於修改和擴充,常常會將負責不一樣功能的語句集中起來並且按照用途分別放置,以便可以反覆調用,而這些獨立放置且擁有不一樣功能的語言,便是「過程」(Procedure)。
存儲過程(Stored Producedures)是一組爲完整特定功能的SQL語句集,經編譯後存儲在數據庫中。用戶經過指定存儲過程的名字給出參數(若是該存儲過程帶有參數)來執行它。
它可以包含執行各類數據庫操做的語句,而且能夠調用其餘的存儲過程;可以接受輸入參數,並以輸出參數的形式將多個數據值返回給調用程序(Calling Procedure)或批處理(Batch);向調用程序或批處理返回一個狀態值,以代表成功或失敗(以及失敗的緣由)。負載均衡
(2).存儲過程的優勢
<1>.存儲過程優勢
A.執行速度快。
存儲過程只在創造時進行編譯,已經經過語法檢查和性能優化,之後每次執行存儲過程都不需再從新編譯,而咱們一般使用的SQL語句每執行一次就編譯一次,因此使用存儲過程可提升數據庫執行速度。
B.容許組件式編程。
常常會遇到複雜的業務邏輯和對數據庫的操做,這個時候就會用SP來封裝數據庫操做。當對數據庫進行復雜操做時(如對多個表進行Update,Insert,Query,Delete時),可將此複雜操做用存儲過程封裝起來與數據庫提供的事務處理結合一塊兒使用。只需建立存儲過程一次並將其存儲在數據庫中,之後便可在程序中調用該過程任意次。在代碼上看,SQL語句和程序代碼語句的分離,能夠提升程序代碼的可讀性。
存儲過程能夠設置參數,能夠根據傳入參數的不一樣重複使用同一個存儲過程,從而高效的提升代碼的優化率和可讀性。
C.減小網絡流量。
一個須要數百行Transact-SQL代碼的操做由一條執行過程代碼的單獨語句就可實現,而不須要在網絡中發送數百行代碼。
對於同一個針對數據庫對象的操做,若是這一操做所涉及到的T-SQL語句被組織成一存儲過程,那麼當在客戶機上調用該存儲過程時,網絡中傳遞的只是該調用語句,不然將會是多條SQL語句。從而減輕了網絡流量,下降了網絡負載。
D.提升系統安全性。
可將存儲過程做爲用戶存取數據的管道。能夠限制用戶對數據表的存取權限,創建特定的存儲過程供用戶使用,避免非受權用戶對數據的訪問,保證數據的安全。
<2>.存儲過程缺點:
A.移植性差。依賴於數據庫廠商,難以移植(當一個小系統發展到大系統時,對數據庫的要求也會發生改變);
B.難以調試、維護。業務邏輯大的時候,封裝性不夠,難調試難以維護;
C.服務器不能負載均衡。複雜的應用用存儲過程來實現,就把業務處理的負擔壓在數據庫服務器上了。沒有辦法經過中間層來靈活分擔負載和壓力.均衡負載等。
(3).存儲過程分類
<1>.系統存儲過程
系統存儲過程(System Stored Procedures)主要存儲在master數據庫中,並以sp_爲前綴,而且系統存儲過程主要是從系統表中獲取信息,從而爲系統管理員管理SQL Server提供支持。
<2>.本地存儲過程
本地存儲過程(Local Stored Procedures)也就是用戶自行建立在用戶數據庫中的存儲過程。事實上通常所說的存儲過程值得就是本地存儲過程。用戶建立的存儲過程是由用戶建立並能完成某一特定功能(如查詢用戶所需的數據信息)的存儲過程。
<3>.臨時存儲過程
臨時存儲過程(Temporary Stored Procedures)可分爲如下兩種:
A.本地臨時存儲過程
若是在建立存儲過程當中,以井號(#)做爲其名稱的第一個字符,則該存儲過程將成爲一個存放在tempdb數據庫中的本地臨時存儲過程(例如,CREATE PROCEDURE #book_proc.....)。本地臨時存儲過程只有建立它的鏈接的用戶纔可以執行它,並且一旦這位用戶斷開與SQL Server的鏈接,本地臨時存儲過程就會自動刪除,固然,這位用戶也能夠在鏈接期間用DROP PROCEDURE命令刪除多建立的本地臨時存儲過程。
B.全局臨時存儲過程
若是在所建立的存儲過程名稱是以兩個井號(# #)開始,則該存儲過程將成爲一個存儲在tempdb數據庫中的全局臨時存儲過程,若是沒有,便當即將全局臨時存儲過程刪除;若是有,SQL Server會讓這些執行中的操做繼續進行,可是不容許任何用戶再執行全局臨時存儲過程,等到全部未完成的操做執行完畢後,全局臨時存儲過程就會自動刪除。
因爲全局臨時存儲過程可以被全部的鏈接用戶使用,所以,必須注意其名稱不能和其餘鏈接所採用的名稱相同。
<4>.遠程存儲過程
遠程存儲過程(Remote Stored Procedures)是位於遠程服務器上的存儲過程,一般可使用分佈式查詢和EXECUTE命令執行一個遠程存儲過程。
<5>.擴展存儲過程
擴展存儲過程(Extended Stored Procedures)是用戶可使用外部程序語言編寫的存儲過程。擴展存儲過程在使用和執行上與通常的存儲過程徹底相同。能夠將參數傳遞給擴展存儲過程,擴展存儲過程也可以返回結果和狀態值。
爲了區別,擴展存儲過程的名稱一般以xp_開頭。擴展存儲過程是以動態連接庫(DLLS)的形式存在,能讓SQL Server動態的裝載和執行。擴展存儲過程必定要存儲在系統數據庫master中。
參考博客:
《SQL Server 存儲過程》
4.事務處理
(1).什麼是事務?
事務是單個的工做單元。若是某一事務成功,則在該事務中進行的全部數據更改均會提交,成爲數據庫中的永久組成部分。若是事務遇到錯誤且必須取消或回滾,則全部數據更改均被清除。事務做爲一個邏輯工做單元有4個屬性,稱爲ACID(原子性、一致性、隔離性和持久性)屬性。
<1>.原子性:事務必須是原子工做單元,對於其數據修改,要麼全都執行,要麼全都不執行。
<2>.一致性:事務在完成時,必須使全部的數據都保持一致狀態。在相關數據庫中,全部規則都必須應用於事務的修改,以保持全部數據的完整性。事物結束時,全部的內容數據結果都必須是正確的。
<3>.隔離性:由併發事務所做的修改必須與任何其餘併發事務所做的修改隔離,保證事務查看數據時數據處於的狀態,只能是另外一併發事務修改它以前的狀態或者是另外一事務修改它以後的狀態,而不能中間狀態的數據。
<4>.持久性:事務完成以後對系統的影響是永久性的。
(2).事務分類
<1>.顯式事務:用begin transaction明確指定事務的開始。
<2>.隱性事務:打開隱性事務:set implicit_transactions on,當以隱性事務模式操做時,SQL Servler將在提交或回滾事務後自動啓動新事務。沒法描述事務的開始,只須要提交或回滾事務。
<3>.自動提交事務:SQL Server的默認模式,它將每條單獨的T-SQL語句視爲一個事務。若是成功執行,則自動提交,不然回滾。
參見博客:
《SQL SERVER事務處理》
5.SQL Server內部函數
內部函數的做用是用來幫助用戶得到系統的有關信息、執行有關計算、實現數據轉換以及統計功能等。SQL所提供的內部函數又分爲系統函數、日期函數、字符串函數、數學函數、集合函數等幾種。
(1).系統函數
系統函數可幫助在不直接訪問系統表的狀況下,獲取SQL Server系統表中的信息。系統函數對SQL Server服務器和 數據庫對象進行操做,並返回服務器配置和數據庫對象數值等信息。系統函數可用於選擇列表、WHERE子句以及任何容許使用表達式的地方。
系統函數 | 功能 |
---|---|
APP_NAME() | 返回當前會話的應用程序名稱(若是應用程序進行了設置) |
CASE表達式 | 計算條件列表,並返回表達式的多個可能結果之一。 |
CAST(expression AS data_type) | 將表達式顯示轉換爲另外一種數據類型。 |
CONVERT(data_type[length],expression[,style]) | 將表達式顯示轉換爲另外一種數據類型。CAST和CONVERT提供類似的功能。 |
COL_LENGTH | 返回列長度而不是列中存儲的任何單個字符串的長度。 |
CURRENT_TIMESTAMP | 返回當前日期和時間。此函數等價於GETDATE()。 |
CURRENT_USER | 返回當前的用戶,此函數等價於USER_NAME()。 |
DATALENGTH(expression) | 返回表達式所佔用的字節數。 |
GETANSINULL(['database']) | 返回會話的數據庫的默認爲空值。當給定數據庫爲空值時容許空值而且列或數據類型爲空值沒有顯示定義,GETANSINULL返回1。 |
HOST_ID() | 返回主機標識。 |
HOST_NAME() | 返回主機名稱。 |
IDENT_CURRENT('table_name') | 任何會話和任何範圍中對指定的表生成的最後標識值. |
IDENT_INCR('table_or_view') | 返回表的標識列的標識增量。 |
IDENT_SEED('table_or_view') | 返回種子值,該值是在帶有標識列的表或視圖中建立標識列時指定的值。 |
IDENTITY(data_type[,seed,increment]) AS col_name | 只在SELECT IINTO生成新表中的標識列。 |
ISDATE(expression) | 表達式爲有效日期格式時返回1,不然返回0。 |
ISNULL(check_expression,replacement_value) | 表達式值爲NULL,用指定的替換值進行替換 |
ISNUMERIC(expression) | 表達式爲數值類型時返回1,不然返回0。 |
NEWID() | 生成全局惟一標識符。 |
NULLIF(expression,expression) | 若是兩個指定的表達式相等,則返回空值。 |
PARSENAME('object_name','object_part') | 返回對象名的指定部分。 |
PERMISSIONS([objectid[,'column']]) | 返回一個包含位圖的值,代表當前用戶的語句,對象或列權限。 |
ROWCOUNT_BIG() | 返回執行最後一個語句所影響的行數。 |
SCOPE_IDENTITY() | 插入當前範圍IDENTITY列中的最後一個標識值。 |
SERVERPROPERTY(propertyname) | 返回服務器屬性的信息。 |
SESSIONPROPERTY(option) | 會話的SET選項。 |
STATS_DATE(table_id,index_id) | 對table_id和index_id更新分配頁的日期。 |
USER_NAME([id]) | 返回給指定標識號的用戶數據庫的用戶名。 |
(2).日期函數
日期函數用來顯示日期和時間的信息。它們處理datatime和smalldatetime的值,並對其進行算術運算。
日期函數 | 功能 |
---|---|
GETDATE() | 返回服務器當前的系統日期和時間。 |
DATENAME(日期元素,日期) | 返回指定日期的名字,返回字符串。 |
DATERART(日期元素,日期) | 返回指定日期的一部分,返回整數。 |
DATEDIFF(日期元素,日期1,日期2) | 返回兩個日期間的差值並轉換爲指定日期元素形式 |
DATEADD(日期元素,日期) | 將日期元素加上日起產生新的日期。 |
YEAR(日期) | 返回年份(整數) |
MONTH(日期) | 返回月份(整數) |
DAY(日期) | 返回某月幾號的整數值 |
GETUTCDATE() | 返回表示當前UTC時間(世界時間座標和格林尼治報紙時間)的日起值 |
日期元素參照:
日期元素 | 縮寫 | 取值 |
---|---|---|
year | yy | 1753-9999 |
month | mm | 1-12 |
day | dd | 1-31 |
Day of year | dy | 1-366 |
week | wk | 0-52 |
weekday | dw | 1-7 |
hour | hh | 0-23 |
minute | mi | 0-59 |
quarter | 1-4 | |
second | ss | 0-59 |
millisecond | ms | 0-999 |
(3).字符串函數
字符串函數用於對字符串進行鏈接、截取等操做。
字符串函數 | 功能 |
---|---|
ASCII(字符表達式) | 返回字符表達式最左邊字符的ASCII碼。 |
CHAR(整型表達式) | 講一個ASCII碼轉換成字符,ASCII碼應在0-255之間。 |
SPACE(整型表達式) | 返回n個空格組成的字符串,n整型表達式的值。 |
LEA(字符表達式) | 返回字符表達式的字符(而不是字節)個數,不計算尾部空格 |
RIGHT(字符表達式,整型表達式) | 從字符表達式中返回最右邊n個字符,n爲整型表達式. |
LEFT(字符表達式,整型表達式) | 從字符表達式中返回最左邊n個字符,n爲 整型表達式. |
SUBSTRING(字符表達式,起始點,n) | 返回字符串表達式中從「起始點」開始的n個字符. |
STR(浮點表達式[,長度[,小數]]) | 將浮點表達式轉換爲所給定長度的字符串,小數點後的位數由所給出的「小數」決定。 |
LTRIM(字符表達式) | 去掉字符表達式的前導空格。 |
RTEIM(字符表達式) | 去掉字符表達式的尾部空格。 |
LOWER(字符表達式) | 將字符表達式的字母轉換爲小寫字母。 |
UPPER(字符表達式) | 將字符表達式的字母轉換爲大寫字母。 |
REVERSE(字符表達式) | 返回字符表達式的逆序。 |
DIFFERENCES(字符表達式1,字符表達式2) | 返回兩個字符表達式發音的類似程度(0-4),4爲發音最類似。 |
PATINDEX("%模式%",表達式) | 返回指定模式在表達式中的起始位置,找不到時爲0。 |
PEPLICATE(字符表達式,整型表達式) | 將字符表達式重複屢次,整數給出的是重複次數. |
SOUNDEX(字符表達式) | 返回字符表達式所對應的4個字符的代碼。 |
NCHAR(整型表達式) | 返回Unicode的字符。 |
UNICODE(字符表達式) | 返回字符表達式最左側字符的Unicode代碼。 |
STUFF(字符表達式,start,length,字符表達式2) | 字符表達式1中從start開始的length個字符換成字符表達式2。 |
CHARINDEX(字符表達式1,字符表達式2,[開始位置]) | 返回字符表達式1在字符表達式2的開始位置,能夠從所給的「開始位置」進行查找, 若是沒指定開始位置,或者指定爲負數或0,則默認從字符表達2的開始位置查找。 |
(4).數學函數
數學函數 | 功能 |
---|---|
ABS(數值表達式) | 返回表達式的絕對值(正值)。 |
ACOS(浮點表達式) | 返回浮點表達式反餘弦值(單位爲弧度)。 |
ASIN(浮點表達式) | 返回浮點表達式反正弦值(單位爲弧度)。 |
ATAN(浮點表達式) | 返回浮點表達式反正切值(單位爲弧度)。 |
ATAN2(浮點表達式1,浮點表達式2) | 返回以弧度爲單位的角度值,此值的反正切值在所給的浮點表達式1和浮點表達式2之間。 |
COS(浮點表達式) | 返回浮點表達式三角餘弦值。 |
COT(浮點表達式) | 返回浮點表達式三角餘切值。 |
CEILIGN(數值表達式) | 返回大於或等於數值表達式的最小整數。 |
DEGREES(數值表達式) | 將弧度轉換爲度。 |
EXP(浮點表達式) | 返回數值的指數形式。 |
FLOOR(數值表達式) | 返回大於或等於數值表達式的最大整數,CEILIGN的反函數 |
LOG(浮點表達式) | 返回數值的天然對數值。 |
LOG10(浮點表達式) | 返回以10爲底浮點數的對數。 |
PI() | 返回的值3.1415962653。 |
POWER(數值表達式,冪) | 返回數字表達式的指定次冪的值。 |
RADIANS(數值表達式) | 將度轉換爲弧度,DEGREES反函數。 |
RAND(整數表達式) | 返回一個0-1之間的隨機十進制數。 |
ROUND(數值表達式,整數表達式) | 將設置表達式四捨五入爲整型表達式所給的精度。 |
SIGN(數值表達式) | 符號函數,正數返回1,負數返回-1,0返回0。 |
SQUARE(浮點表達式) | 返回浮點表達式的平方。 |
SIN(浮點表達式) | 返回浮點表達式的三角正弦值(弧度爲單位)。 |
SQRT(浮點表達式) | 返回一個浮點表達式的平方根。 |
TAN(浮點表達式) | 返回浮點表達式正切值(弧度爲單位)。 |
(5).集合函數
集合函數也稱爲統計函數,它對一組進行計算並返回一個數值。聚合函數常常與SELECT語句的子句一塊兒使用。
聚合函數 | 功能 |
---|---|
SUM([ALL|DISTINCT]expression) | 計算一組數據的和 |
MIN([ALL|DISTINCT]expression) | 給出一組數據的最小值 |
MAX([ALL|DISTINCT]expression) | 給出一組數據的最大值 |
COUNT([ALL|DISTINCT]expression|*) | 計算總行數。COUNT(*)返回行數,包括含有空值的行,不能與DISTINCT一塊兒使用 |
CHECKSUM(*|expression[,...n]) | 對一組數值的和進行校驗,可探測表的變化 |
BINARY_CHECKSUM(*|expression[,...n]) | 對二進制的和進行校驗,可探測表的變化 |
AVG([ALL|DISTINCT]expression) | 計算一組值的平均值 |