索引和檢視第十一次課
1 索引-index
1)概念理解
如學生花名冊,預設是學生有序的,今天的新申請的QQ號數字比以前申請的要大。如此,這些資料有序的,主要目的是方便以後查詢。
資料表事先按要查詢的關鍵字列索引後,以後要查詢時可以使用二分查詢或其他跟資料有序有關的查詢。如我們經常按使用者ID號或使用者名稱登陸等操作,可以對資料原表建立一個附屬的檔案,儲存查詢依據的記錄順序。但這樣做要增加額外的儲存空間,增加資料的複雜度,但最大好處是提高查詢效率。 從順序查詢的n/2 降到log2(n)
引例:
如有學生表
隱藏的記錄號 學號 姓名 身高
1 01 張三 175
2 02 李四 165
3 05 張六 181
4 04 陳東
5 03 艾化
如果學生進入系統,按學號登陸,學號無序,只能順序查詢,如果有n個學生,每個學生登陸時平均表中查詢次數 n/2次.
如果事先針對學號列建立索引(按學生排列的每個記錄的位置,出場順序記錄下來)
Index_xh 又可按姓名建立索引 index_xm
01 ->1 艾化 ->5
02->2 陳東 -> 4
03->5 李四->2
04 ->4 張六->3
05->3 張三->1
可見,如果有了索引後,變順序查詢為二分查詢,有N個記錄,平均查詢次數從n/2降到 log2(n)。如對100萬個記錄中資料查詢,平均查詢次從50萬降到20次
如下圖:索引表是按學號Sno的值的升序/降序排序,每個值後有一個指標,指向物理中對應的記錄的物理位置。
缺點:增加儲存空間(但比把原表複製成一個有序的新表空間開銷少),資料複雜度,如果物理表中的資料,特別是索引關鍵字經常變動,經常增刪,必須要重新索引一次,對海量的資料來說,重新索引一次是很耗費資源。所以索引,並不適合經常增刪改關鍵字的表。如學校教務處的學生表可以建立索引;對貼吧裡的貼子表不適合建立索引.
索引B-樹結構機制:
2)索引分類
(1)聚集索引 clustered index )
把資料按索引項的順序進行物理排序。要生成一個新表,完全打亂原表中原資料的物理位置。
(2)非聚集索引 (non clustered index)
現實開發相對說用得較多。一般是一個索引針對一表的一列(也可以是多列較少見),針對一列建立一個索引,一個表可以建立多個索引的。如果使用聚集索引不現實。非聚集索引就是上面的理論的實際應用,針對一個物理表,可以建立多個附屬的索引表,並不打亂原物理的記錄順序,只是重新記錄原表記錄的位置。
例:以非聚集索引為例說明實際索引結構。索引使用資料頁管理,可以把大量的資料分段管理,大大提高查詢效率(使用B樹採用折半查詢更快)
3)應用
例1 為學生表的姓名列建立一個非聚集索引(以後使用者使用姓名查詢人,非常快).
當用戶查select ….from … where 姓名=…..,系統自動啟動姓名索引幫助使用者提高查詢效率
create index index_xm on 學生表(姓名)
建立學號索引:
create index index_xh on 學生表(學號)
注:有時原物理中索引列有重複值,索引後,重複值只保留一個值在索引表中
Create unique index index_xm on 學生表(姓名)
2 檢視-view
資料庫中的建立的表table叫物理表; view是查詢結果的儲存,它是虛擬表
檢視分:使用select命令查詢出的結果,是臨時,用完就關閉---臨時的檢視
某個查詢結果我們要以後再使用,可以把查詢的命令儲存起來,叫虛擬表,永久檢視。(檢視本身不是物理表,檢視本身是無資料,就是一個可簡單可複雜的select命令)
例:程式設計時經常要使用學生表和成績兩個表,為避免每次書寫連線命令。把操作成功後的這個查詢命令儲存起來.
create view myvv1 as
(select a.*,課程號,成績 from 學生表 a inner join 成績表 b on a.學號=b.學號)
生成一個檢視,myvv1,它可以當表一樣使用,其實它就是一個查詢命令。
select * from myvv1
myvv1檢視的內容究竟是啥?
檢視可以在平時當成一般表用,但它本身並不存放資料,當使用到檢視時,它去執行內部SELECT命令。
檢視也可以作為其它檢視的資料來源。
select a.*,課程號,成績 into myvv1 from
學生表 a inner join 成績表 b on a.學號=b.學號
這個不是檢視,生成一個物理新表,脫離了與學生表和成績表的關係,當成績表和學生表的資料發生變化時,不影響myvv1表。
而上面的檢視myvv1它在任何時刻的資料來源都是實時來自於學生表和成績表.
例2:在上面myvv1檢視基礎,再連線課程表,生成一個myvv2檢視,包括三個表的資料
create view myvv2 as
(Select myvv1.學號,姓名,生日,myvv1.課程號,成績,名稱,學分
From myvv1 inner join 課程表 on myvv1.課程號=課程表.課程號 )
select * from myvv2
可見,檢視的利用,可以大大簡化sql的查詢命令的書寫。在一個開發中,把經常要用的多個表提前建立檢視。
例:建立一個檢視myvv3,要得資料有:學號,姓名,課程號,成績,及格否
create view myvv3 as
(select 學生表.學號,姓名,課程號,成績,
case when 成績>=60 then '及格'
else '不及格'
end as 及格否
from 學生表 inner join 成績表 on 學生表.學號=成績表.學號)
select * from myvv3
檢視修改:最方便的是刪除了重新建立(先把原核心的sele命令複製下來)
檢視刪除:drop view 檢視名
總結
1 索引可提高查詢效率
2 檢視:
- 簡化查詢命令語句的書寫
- 使用使用者從多角度檢視同一個資料(資料來源於同一個物理表,但可能看到結果大不一樣)
- 提高資料的安全性。如對敏感資料加密,或不授予許可權,但通過檢視可以開放查詢結果。普通使用者看不到原表物理資料。
- 提供一定程式的邏輯獨立性
開發應用(dataset)
C++/c#連線SQLSERVER目前最流行的資料連線技術是ADO.NET2.0
1 dataset概念:記憶體資料庫,是表的查詢結果的檢視集合,一個dataset是存在於記憶體中的,用於臨時存放使用者查詢的結果,第三方語言從它裡面再提出資料到使用者介面。一個dataset可以存放若干個檢視。
磁碟上的資料庫叫物理資料庫,是提供資料最原始的來源。記憶體資料庫dataset是記憶體臨時的資料庫。一但從物理資料庫把資料載入了dataset,可以與物理資料庫斷開連線,資料庫可以被其它使用者或APP使用,這種方法遠比datareader高效,共享性好。
Datareader 是一種不斷開資料庫的應用,在整個資料讀取過程中,它是保持與物理資料庫連線狀態,所以資料庫獨佔,共享性差。
而dataset可以快速地把物理資料庫載入,然後物理資料庫不需要保持與dataset 的連線狀態。每個使用者可以在伺服器上獨立地建立一個自己的記憶體資料庫。
打個比方:多個人在一個盆子裡吃飯。datareader
多個人從盆子裡把飯載入自己的小碗裡,然後再慢慢吃.dataset
2 使用dataset 的基本步驟:
(1) 建立與資料庫連線cn
(2) 定義記憶體資料庫dataset
(3) 定義在物理資料庫與記憶體資料庫之間運輸資料的介面卡dataadapter
(4) 把查詢的結果資料填充到datasest
(5) 從dataset中提出資料使用
string xs = TextBox1.Text.Trim(); //習慣性地去掉多餘空格
資料庫應用例項:
前臺程式:
見壓縮檔案 “資料庫查詢例項.rar”,講解了連線模組化,查詢返回資料模組化,介面展示資料結果模組化