算法是計算機科學中一個重要的研究方向,是解決復雜問題的關鍵。在計算機世界中,算法無處不在。數據庫是存儲數據和執行大批量計算的場所,在數據庫中使用一些簡單的SQL命令,進行存儲、查詢、統計、以解決現實世界中的問題已經是屢見不鮮。隨著數據量的大幅度增加和業務規則的日益復雜,越來越需要一種專門的方法來滿足效率和准確性方面的要求。如何把解決問題的復雜算法轉換為數據庫能夠執行的命令,也是數據庫應用技術研究的一個方面。本文以MSSQL中的命令來闡述例子。
數據庫中可以存儲實體的數據集合,在進行運算時,數據庫使用批量計算的方法來處理數據,批量的從存儲設備上讀取數據,處理之後又批量的寫回存儲設備。有的數據庫提供了游標,游標可以讀取出表中一行的數據中的每一個字段,對這些字段進行復雜的業務規則計算,然後再寫回數據庫中。與使用批量的方法比較,批量計算的方法消耗的資源相對比較少,而使用游標則占用太多的資源,速度比較慢,效率較低並且還有加鎖條件等許多的限制。
比如對於數據庫中存儲了學生成績student_Score(sno,cno,score,level),成績從0分到100分不等,如果需要在分數的後面存儲一個字段字level來說明成績的優劣,90分以上的A,80-90分為B,60-80分的為C,60分以下的為D,以下有幾種算法都可以達到同樣的目標:
1.定義一個游標,選擇student_Score表中所有的成績記錄,定義一個存儲成績的變量@cur_score,存儲當前紀錄的分數,定義一個存儲當前分數所在成績級別的變量@cur_level,用以存儲成績好壞的標記。算法如下:如果游標中的紀錄不為空,從游標中取出當前紀錄的成績,判斷成績所在的分數段,把結果存儲在變量@cur_level中,以@cur_level中的值更新當前紀錄中的level字段。整個過程需要至少讀取數據庫兩次,一次為獲得紀錄,一次需要寫入數據庫,每條記錄都需要經過這個過程,效率相對低。
2.依次批量更新數據庫,把所有的level字段的值設置為D,再次更新數據庫,把成績大於等於60的紀錄的Level字段更新為C,依次更新B、A。這樣做的一個缺點是有些紀錄的Level字段被更新多次,比如一個記錄最後的Level字段的值是A,則它首先被更新為D,依次被更新為C、B、A。這些重復的更新是可以被消除的,把算法改進一下就可以省去重復更新的花費。更新後的算法是這樣的,把成績介於0和60分的紀錄的Level字段更新為D,依次更新各個分數段的成績。實現的這種算法的SQL語句並不難寫出,使用Between…and…表達式即可以表達例如介於80到90之間紀錄的選擇條件。
3.鑒於第二種方法最後的分析,使用between…and…表達式同時參照一個表來更新紀錄,則可以方便表達分數段與相應的level信息,把這些信息存儲到一個表level_about中,在更新student_score表的過程中可以參照這個表。計算的過程中,需要把level_about表的內容讀出來,然後進行計算。對於整個計算過程來說,犧牲空間和部分效率來換來操作方便,,由於現在計算機的速度相當快,level_about表占用的空間又很小,這方面的損失可以忽略不記。Level_about表中的信息至少包含3個字段:start_score,記錄起始分數,end_score記錄終止分數,level記錄介於起始分數和終止分數之間的分數應該得到的成績。表中的數據應該類似於這樣:
Start_score End_score level
0 59 D
60 79 C
80 89 B
90 100 A
更新student_Score表中的紀錄需要依據Start_score和End_score來判斷當前記錄中成績所在的Level,在MSSQL中實現的SQL語句:
Update student_score set
student_score.level=level_about.level from
level_about where student.score
between level_about.start_score and level_about.end_score