SQL SERVER-8-檢視|事務|索引
1.檢視 --檢視是一張虛擬表,他表示一張表的部分資料或者多張表的綜合資料,其結構和資料是建立在堆表的查詢基礎上的 --檢視在操作上和表沒有任何區別,但是他們的本質是不同的,資料表儲存資料,但是檢視是不儲存資料的(sql server的索引檢視除外,索引檢視是儲存資料的) --檢視的目的是方便查詢,所以一般情況下是不能對檢視進行增刪改的操作的
--檢視一般分為普通檢視和索引檢視 --普通檢視是不儲存資料的,但是索引檢視是儲存資料的
--建立一個檢視(普通檢視) create view vw_Employees as select e1.EmployeeId as EmpId, e1.LastName as LastName, e1.FirstName as FirstName, e1.ReportsTo as ReportsTo, e2.FirstName as ReportsToName from Employees as e1 left join Employees as e2 on e1.ReportsTo=e2.EmployeeId
--查詢一下 select * from vw_Employees
--注意:在子查詢,或檢視等中不能使用order by子句,除非指定了top語句 --否則會報錯:除非另外還指定了TOP 或者FOR XML,否則,ORDER BY子句在檢視,行內函數,派生表,子查詢,公用表表達式中無效 --這是因為檢視是一個結果集,而一旦order by之後就是一個有序的集合了
--這裡是修改了檢視vw_Employees --直接使用order by 是不行的,但是如果使用 top 100 percent 返回100%的資料的時候,則是可以使用的 --但是這時候是沒有意義的,如下,order by 查詢的時候是按降序排序的,但是直接top之後再使用檢視查詢則排序又變成了升序 --這是應為top 把有序的集合變成了一個無需的結果集 alter view vw_Employees as select top 100 percent e1.EmployeeId as EmpId, e1.LastName as LastName, e1.FirstName as FirstName, e1.ReportsTo as ReportsTo, e2.FirstName as ReportsToName from Employees as e1 left join Employees as e2 on e1.ReportsTo=e2.EmployeeId order by EmpId desc
2.事務 --強調的是一個過程,整個過程都不能出錯,如果那一步出錯了就把整個過程都給回滾,保持一致性 --比如轉賬,扣款和收錢兩步要成功都成功,要失敗都失敗
select * from bank; --一個人扣1000元 update bank set balance=balance -1000 where cid='0001' --另外一個人收到1000元 update bank set balance=balance +1000 where cid='0002' --如上兩步,如果其中一步操作失敗,而另一個執行成功 --會導致一個人的錢扣了,但是另一個人沒有接收到錢 --或者一個人的錢沒有扣除成功,但是另一個人的錢增加了(這個好 。。。)
--把這兩句話放到一個事務中 begin transaction --定義一個變數,用來儲存操作是否成功的表示號 declare @sumErrors int --設定初始值為0 set @sumErrors=0 --執行扣款操作 update bank set balance=balance-1190 where cid='0001' --立刻驗證一下這句話是否執行成功了,把返回的錯誤資訊標識與定義的變數相加 set @[email protected][email protected]@error --執行轉入操作 update bank set balance=balance+1190 where cid='0002' --把錯誤資訊表示號與定義的變數相加 set @[email protected][email protected]@error --驗證是否執行成功 if @sumErrors=0 begin --表示沒有出錯 --開始提交事務,transaction可以省略 commit transaction end else begin --否則表示在操作的過程中出現了錯誤,回滾操作的資料,transaction可以省略 rollback transaction end --預設Sql Server是自動提交事務 --在執行完操作語句之後,會直接commit提交 insert .... commit ..
--鎖定 --新開一個事務 begin transaction --執行修改操作 update TblClass set tclassName='Black Seven' where tclassId=24 --這時候如果不進行提交,(不執行下面的提交語句) --直接在對該表進行查詢操作,則查詢會一直處於等待狀態,而無法返回查詢結果 --這是應為在進行修改的時候會對錶進行加鎖,使表被獨佔,而無法在才被其他操作所使用,只要執行了提交,查詢結果會立刻顯示出來 --select * from TblClass commit transaction
--事務一旦開啟就只有兩種結果 --要麼執行完畢提交操作,要麼回滾事務撤銷所有操作
--事務的特性 --1.原子性,事務必須是原子工作單位,對於資料的操作要麼全部執行,要麼全部不執行 --2.一致性,事務在執行之後,資料庫中的資料必須保持一致狀態 --比如在轉賬的時候,轉入和轉出之後的總金額必須相同的 --3.隔離性,由併發事務所做的修改,必須與其他任何併發事務是隔離的 --事務識別資料所處的狀態,要麼是另一併發事務修改它之前的狀態,要麼是另一併發事務修改它之後的狀態,事務不會識別中間狀態的資料 --4.永續性,事務完成之後,對系統的影響將是永久的 --一旦事務提交完成,資料庫中的資料就不會再改變了,在提交之前應為可能會出錯回滾,所以資料還是不固定的
3.索引 --為了提高查詢的資料,他是對資料進行了排序,然後可以根據一定的演算法快速定位到資料行找到需要的資料 --這裡的查詢不僅限於select,刪除和更相信的時候應為有where條件的存在,在語句執行之前也是有查詢的過程,找到需要操作哪個資料 --所以這裡的查詢在select,delete,update的時候都有
--索引的分類 --1.聚集索引(聚簇索引),指索引實際儲存的順序,和表中物理儲存的資料是相同的,找到該索引之後直接指向磁碟的空間位置,效率會比較高 --一個表中只能有一個聚集索引,應為磁碟的位置是固定的,既然已經存在一個聚集索引,再建立的話儲存的順序還是相同的,所以沒必要建立多個聚集索引 --一般在建表以後要先建一個聚集索引,然後在建立其他索引 --其他索引依賴於聚集索引 --建立聚集索引的時候儘量避免選擇那些頻繁更新的列,否則排序以及索引所對應的地址都會改變,會降低效能 --2.非聚集索引(非聚簇索引),非聚集索引根據值獲取聚集索引對應的值,然後根據聚集索引獲取對應的磁碟空間的地址,之後再找到相應大的資料
--不要在比較大的欄位上面建立索引 --比如下面的型別的欄位,最好不要建立索引 --ntext --text --varchar(max) --nvarchar(max)
--索引是為了降低讀取磁碟的IO操作的次數 --應為磁碟的讀取效率是比較低的,但是讀取記憶體的效率是比較高的
--如果有多個索引存在 --在執行操作的時候查詢優化器會對查詢進行優化,找到最佳的索引並使用 --所以在進行查詢操作的時候不要指定使用哪個索引 --有可能指定的索引效率並不是最優的,反而會消耗更多的時間
--沒有索引的時候執行查詢,獲取查詢時間 --如果多次執行,之後的執行時間會稍微短一些,應為快取的存在 select * from TestIndex1002 where c4>700 and c4<1800 order by c4 desc
--建立聚集索引 --為表TestIndex1002的c4列建立一個聚集索引 --建立了聚集索引之後再次查詢,時間會變短,讀取次數會明顯減少 --在c4列建立索引,在查詢的時候就需要使用該欄位,否則索引不會起效果 create clustered index ic4 on TestIndex1002(c4)
--建立非聚集索引 --在表TestIndex1003的c3欄位建立一個非聚集索引 create index ic3 on TestIndex1003(c3)
--刪除索引,需要指定表名.索引名稱 --下面的刪除語句刪除了TestIndex1003上面的ic3索引 drop index TestIndex1003.ic3