今天來分享下T-SQL高級編程中的事務、索引、視圖,可以和之前的SQL server系列文章結合起來。
一、事務
事務(TRANSACTION)是作為單個邏輯工作單元執行的一系列操作,這些操作作為一個整體一起向系統提交,要么都執行、要么都不執行,事務是一個不可分割的工作邏輯單元
這樣說可能太籠統,看個實例就會清晰很多,比如銀行轉賬業務,相信大家都辦理過。
create table bank ( customerName char(10), --顧客姓名 currentMoney money --當前余額 ) go alter table bank add constraint CK_currentMoney check(currentMoney>=1) go insert into bank(customerName,currentMoney) values('張三',1000) insert into bank(customerName,currentMoney) values('李四',1) --模擬銀行轉賬: /*--轉賬測試:張三轉賬1000元給李四--*/ --我們可能會這樣這樣編寫語句 --張三的賬戶少1000元,李四的賬戶多1000元 UPDATE bank SET currentMoney=currentMoney-1000 WHERE customerName='張三' UPDATE bank SET currentMoney=currentMoney+1000 WHERE customerName='李四' GO --再次查看轉賬后的結果。 SELECT * FROM bank GO
這樣寫的SQL代碼,實際結果會出現,張三的錢沒少,而李四的錢多了1000,是因為添加的約束條件,money要>=1,才導致這樣結果。
轉賬那個人的錢沒少,而另一方卻收到了錢,這樣的話,銀行豈不虧死,所以,這樣的代碼明顯是不合理的。根據事務概念,是要么執行成功,要是失敗,只有這兩種結果,而且是同步的。
代碼改進為如下:
使用事務解決: BEGIN TRANSACTION /*--定義變量,用於累計事務執行過程中的錯誤--*/ DECLARE @errorSum INT SET @errorSum=0 --初始化為0,即無錯誤 /*--轉賬:張三的賬戶少1000元,李四的賬戶多1000元*/ UPDATE bank SET currentMoney=currentMoney-1000 WHERE customerName='張三' SET @errorSum=@errorSum+@@error UPDATE bank SET currentMoney=currentMoney+1000 WHERE customerName='李四' SET @errorSum=@errorSum+@@error --累計是否有錯誤 IF @errorSum<>0 --如果有錯誤<>表示不等於與!=的效果一樣 BEGIN print '交易失敗,回滾事務' ROLLBACK TRANSACTION END ELSE BEGIN print '交易成功,提交事務,寫入硬盤,永久的保存' COMMIT TRANSACTION END GO print '查看轉賬事務后的余額' SELECT * FROM bank GO
添加事務后,就會保證數據的正確性了,到這,我想大家已經明白事務的好處了。
事務的四大屬性,簡稱ACID屬性
原子性(Atomicity):事務是一個完整的操作。事務的各步操作是不可分的(原子的);要么都執行,要么都不執行
一致性(Consistency):當事務完成時,數據必須處於一致狀態
隔離性(Isolation):對數據進行修改的所有並發事務是彼此隔離的,這表明事務必須是獨立的,它不應以任何方式依賴於或影響其他事務
永久性(Durability):事務完成后,它對數據庫的修改被永久保持,事務日志能夠保持事務的永久性
創建事務
開始事務:BEGIN TRANSACTION 提交事務:COMMIT TRANSACTION 回滾(撤銷)事務:ROLLBACK TRANSACTION
一旦事務提交或回滾,則事務結束。
判斷某條語句執行是否出錯:@@ERROR的返回值為0表示沒錯
使用全局變量@@ERROR;
@@ERROR只能判斷當前一條T-SQL語句執行是否有錯,為了判斷事務中所有T-SQL語句是否有錯,我們需要對錯誤進行累計;
如: SET @errorSum=@errorSum+@@error
事務分類:
顯示事務:用BEGIN TRANSACTION明確指定事務的開始,這是最常用的事務類型
隱性事務:通過設置SET IMPLICIT_TRANSACTIONS ON 語句,將隱性事務模式設置為打開,下一個語句自動啟動一個新事務。當該事務完成時,再下一個 T-SQL 語句又將啟動一個新事務
自動提交事務:這是 SQL Server 的默認模式,它將每條單獨的 T-SQL 語句視為一個事務,如果成功執行,則自動提交;如果錯誤,則自動回滾
二、索引
索引根據索引鍵查找定位數據行
索引:是SQL Server編排數據的內部方法。它為SQL Server提供一種方法來編排查詢數據 。
索引頁:數據庫中存儲索引的數據頁;索引頁類似於漢語字(詞)典中按拼音或筆畫排序的目錄頁。
索引的作用:通過使用索引,可以大大提高數據庫的檢索速度,改善數據庫性能。
索引類型
唯一索引:唯一索引不允許兩行具有相同的索引值
主鍵索引:為表定義一個主鍵將自動創建主鍵索引,主鍵索引是唯一索引的特殊類型。主鍵索引要求主鍵中的每個值是唯一的,並且不能為空
聚集索引(Clustered):表中各行的物理順序與鍵值的邏輯(索引)順序相同,每個表只能有一個,比如:拼音
非聚集索引(Non-clustered):非聚集索引指定表的邏輯順序。數據存儲在一個位置,索引存儲在另一個位置,索引中包含指向數據存儲位置的指針。可以有多個,小於249個,比如:偏旁
創建索引
CREATE [UNIQUE] [CLUSTERED|NONCLUSTERED] --唯一索引,聚集索引或非聚集索引 INDEX index_name ON table_name (column_name…) [WITH FILLFACTOR=x]
其中:
UNIQUE表示唯一索引,可選
CLUSTERED、NONCLUSTERED表示聚集索引還是非聚集索引,可選
FILLFACTOR表示填充因子,指定一個0到100之間的值,該值指示索引頁填滿的空間所占的百分比
創建索引舉例:
USE stuDB GO IF EXISTS (SELECT name FROM sysindexes WHERE name = 'IX_writtenExam') DROP INDEX stuMarks.IX_writtenExam /*--筆試列創建非聚集索引:填充因子為30%--*/ CREATE NONCLUSTERED INDEX IX_writtenExam ON stuMarks(writtenExam) WITH FILLFACTOR= 30 GO /*-----指定按索引 IX_writtenExam 查詢----*/ SELECT * FROM stuMarks with(INDEX=IX_writtenExam) WHERE writtenExam BETWEEN 60 AND 90
創建索引的指導原則
請按照下列標准選擇建立索引的列。
該列用於頻繁搜索
該列用於對數據進行排序
請不要使用下面的列創建索引:
列中僅包含幾個不同的值。
表中僅包含幾行。為小型表創建索引可能不太划算,因為SQL Server在索引中搜索數據所花的時間比在表中逐行搜索所花的時間更長
三、視圖
視圖是一張虛擬表,它表示一張表的部分數據或多張表的綜合數據,其結構和數據是建立在對表的查詢基礎上,視圖中並不存放數據,而是存放在視圖所引用的原始表(基表)中,同一張原始表,根據不同用戶的不同需求,可以創建不同的視圖
視圖的用途:
篩選表中的行
防止未經許可的用戶訪問敏感數據
降低數據庫的復雜程度
將多個物理數據庫抽象為一個邏輯數據庫
SQL Server中允許用戶創建視圖,在同一原始數據表的基礎上,為不同的用戶選擇不同的列,從而達到不同用戶的需求。
創建視圖語法:
CREATE VIEW view_name AS <select語句>
舉例:
IF EXISTS (SELECT * FROM sysobjects WHERE name = 'view_stuInfo_stuMarks') 檢查視圖是否存在 DROP VIEW view_stuInfo_stuMarks 刪除視圖 GO CREATE VIEW view_stuInfo_stuMarks 創建視圖 AS SELECT 姓名=stuName,學號=stuInfo.stuNo,筆試成績 =writtenExam,機試成績=labExam,平均分=(writtenExam+labExam)/2 FROM stuInfo LEFT JOIN stuMarks ON stuInfo.stuNo=stuMarks.stuNo GO SELECT * FROM view_stuInfo_stuMarks 使用視圖