1. 程式人生 > 其它 >索引和檢視第十一次課

索引和檢視第十一次課

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”,講解了連線模組化,查詢返回資料模組化,介面展示資料結果模組化