學 習 中 的 思 考
海風
學習計算機知識常常讓人陷入無知的恐懼中,過去打破沙堡問到底的精神在這裡要有所節制了,我們把握好一個度的問題,要明確自己到底現在最應該知道的是些什麼;不執著於現在還不是時候該知道的知識,只於心中存在一個問號待以後有意或無意間來解決。疑問是學習的靈丹妙藥,我常常抱著懷疑的精神去思考書本中敘述的知識,亦常常先入為主去推敲未知的知識,但有發現自己的猜測有正確之處便沾沾自喜,如若有誤亦為書中的解決之道歎服與興奮。采集我?yuXvv
MS sql server 心得與猜想:采集我?yuXvv
數據庫是門高深的學問,有些知識雖然不太清楚,但我們可以推測可以思考。我們知道一個數據庫裡有很多個表,一個表裡有很多字段,一個字段上定義有很多規則。那讓我們想想,一個記錄裡包含所有字段對應的值,而記錄的數量是可變的,字段的個數也是可變的,可變加可變讓我們創建維護管理數據庫帶來了方便,問題是,怎樣實現這樣的功能呢?我們查找數據修改數據時可以選擇指定的字段指定的記錄,我們也一樣用得很高興,可是,為什麼這樣子可行呢?在沒有看過數據庫存儲結構有關書籍之前,讓我大膽地猜測:字段是相對獨立的對象,他擁有自己的屬性,我們用數組鏈表把表中的各個字段鏈接起來,這樣我們就可以動態地增減字段數,各個記錄字段的對應值都應該有指向上一個與下一個對應字段值的指針,這樣就形成一個十字交叉鏈表,記錄也就可以方便地管理了,我們好像也能自由選擇特定的字段來顯示與修改了,而且因為有指針這位大俠的幫忙,數據就可以方便地亂放了;可是,還有問題,增減一個字段好像要修改所有的記錄,我們的SQL語言好像也是面向集合的語言,這樣子的結構可行麼,高效麼?我不知道,我只是隨便想想罷了。還有啊,數據庫裡表與表之間的關系,在儲存結構裡又該如何表述呢?缺省與規則又是如何的綁定到字段呢?唉,算了,到此為止,有空再想。采集我?yuXvv
存儲過程:存儲過程由一組SQL語句組成,他們共同完成一個任務,我們用一個名字(可能還和一些叫參數的符號組成的一串符號)來表示這組語句;那麼,在遠程訪問數據庫時,我們就可以向數據庫所在的服務器發送這個名字,那麼服務器就執行對應的SQL語句組,並返回結果給客務機,這就達到減少發送的數據效果。采集我?yuXvv
觸發器:觸發器定義了一組SQL語句,當我們對指定的表進行修改時,SQL Server 就會觸發對應的觸發器,執行特定的SQL語句組,以保證數據的正確性和一致性。采集我?yuXvv
索引:由索引頁和數據頁組成;索引頁由一個或幾個數據項為關鍵字進行排序而組成,同一個關鍵字可以對應一個以上的記錄,並存儲有指向特定記錄的指針,通過關鍵字的排序可以加快查找記錄的速度,數據頁是實際的存儲數據的頁面。填充因子的作用是:因為在內存與硬盤的數據交換中,總是預先或優先把存儲位置相近的數據調入內存以減少缺頁中斷;所以在每個索引頁中預先留出一部分空間,使得系統在新增索引信息時能夠保持數據的連續性,從而加快查詢速度。采集我?yuXvv
數據庫的安全:我們要使用SQL Server,需要使用一個登錄名來連接SQL服務器,登錄名提供了使用服務器的權力但並沒有提供使用服務器中的數據庫的權力;用戶帳號提供了使用數據庫的權力,所以我需要為登錄名提供一個用戶賬號以便在登錄服務器的同時能使用其中特定的數據庫;不同的用戶賬號使用數據庫的權限是不同的,比如有的用戶只能查看數據而不能修改,有的用戶能夠賦給別的用戶使用數據庫的權力,於是我們使用角色來為擁有不同權限的用戶分類,把擁有相同權限的用用戶集中起來管理,我們在創建數據庫用戶的同時也指定了他在數據中扮演的角色(使用數據庫的權限)。系統管理員與數據庫擁有者擁有管理數據庫的最高權力。我們還可以為數據庫用戶指定對數據庫中的表,視圖,函數,存儲過程所擁有的權限,以從更低級的數據對象來管理數據庫安全。采集我?yuXvv
當我們擁有了使用數據庫應有的權限時,在用戶應用程序中,我們是怎樣使用數據庫中的數據的呢?我們可以使用SELECT語句來創建一個臨時表,應用程序用戶能夠看到的使用的僅限於這個臨時表,這個臨時表擁有指向基表(實際上的有存儲數據的表)對應字段數據的指針,通過這個指針,我們就可以間接地修改選定的表中記錄記段的數據了。臨時表中的指針指向的,可以是基於特定表中特定字段中的數據,擁有如此小對象的數據的地址,我們因此可以聯合查詢修改數個表中的數據。視圖,可以理解為用一個字符串替換一句SELECT語句,以後要使用特定的SELECT時只需使用這字符串替換就行,這樣減輕了我們書寫SELECT語句的負擔,當然也浪費了存儲空間來存儲(存在系統表中)SELECT語句的信息。因為應用程序用戶是通過指針間接訪問數據的,所以當我們改變數據庫的物理存儲結構時,不必修改用戶程序,只需修改用戶程序中臨時表的數據地址就行了,而地址是動態自動分配的,這樣就保證的用戶程序的穩定性。也許改變物理存儲結構,我們只需重新編譯一下索引就行了,索引頁存有數據的地址,臨時表中的地址可方便地從索引頁中獲取,索引頁不大,獲取地址的效率很高。采集我?yuXvv
COM的思考;采集我?yuXvv
在C++語言中,類封裝了數據和操作其中數據的方法(函數),當我們需要操作類中的數據時,我們就需要調用方法函數,要調用函數操作數據就要知道函數的代碼段的地址,在同一進程中,地址可以這樣子表示:類名.函數名。無論你身在何處,只要你有辦法獲取函數的地址,知道函數名的定義,就可以使用函數來操作數據並得到返回結果。於是,當我們有辦法聯接遠程計算機並得到其中可運行程序代碼中的一個函數地址,我們就可以遠程調用(通過網絡傳輸數據)這個函數使之在計算機中運行並將得到返回的結果傳輸回本地計算機上。我們要計算機完成的任務,基本上都是通過調用函數來完成的。於是,在我們的程序中,如果我們知道其他可獨立編譯運行程序中的函數的地址,我們就可以調用他來為我們的程序服務。於是我們就可以把各個相對獨立的程序聯合起來共同完成我們的任務。COM組件對象模型就是為了解決這個技術問題而設計出來的。在COM中,我們設計了各種類型的接口來為函數調用提供地址,每個接口都擁有自己的函數,也可以有自己私有的數據。各個接口類都有一個派生對象作為COM類的一個成員;於是我們就可通過接口類調用(把派生對象地址賦給接口)存在於COM類中的派生對象的成員函數。那麼, COM程序編譯獨立運行,只要能把派生對象地址賦給接口,再在我們需要使用COM中功能的程序中加入接口,調用COM中的函數功能也就能實現了。COM實現了真正的面向對象技術,他把函數的實現細節完全隱藏了起來,COM組件中,可以方便地新增一個接口來實現新的程序功能,只需在原來的代碼加上一個接口代碼就行了,原來的接口仍然可用。COM組件類的存儲結構是以二進制形式順序存儲的,因此只要知道一個接口的地址就可以通過地址偏移量計算出COM其它接口的地址,也就可以方便地實現接口之間的切換了。我們通過接口調用COM中函數,為了使COM能在不同的語言中使用,專家們設計了標准接口語言IDL,以此為中介,實現用各種語言書寫的有相同功能和參數的接口的轉換;當我們用特定語言編寫COM時,先把其接口定義轉換為IDL接口定義的形式,再通過IDL把接口轉換為其它語言所能識別的接口;這樣就實現了COM代碼的重用性與語言無關性。采集我?yuXvv
現在我們遇到的最大問題是:如何創建COM實例並獲取其地址供程序使用,如何實現COM代碼同時被多個程序所共享。這是個令人頭痛的問題,很多地方我都未能理解。為實現COM的共享,我們設計一個所有接口的基類IUnknown接口,IUnknown接口有一個函數QuerInterface來實現接口的切換,一對函數AddRef各Release來增加與減少他的引用計數成員m_dwRef;每當組件返回一個新的接口時,程序就調用AddRef來使m_dwRef加一,當結束一個接口的使用時就調用Release來使m_dwRef減一,當m_dwRef變為0時就刪除組件對象。因為其它接口都是從IUnknown派生而來的,他們繼承了m_dwRef成員,使這個引用計數能正確記錄下正在使用組件的用戶數,實現了共享組件的管理。在ATL實現方案中,專家們設計了一個智能指針來封裝完成有關引用計數的功能,有人稱這種功能的實現者為垃圾收集器。在服務器方面,我們需要做些什麼准備呢?我們需要把CLSID、實現文件名等配置信注冊到注冊表中,以供客戶遠程激活使用。當客戶需要COM服務時,遠程計算機根據客戶發過來的CLSID在內存中查看對應組件是否已被激活,如果已被激活了,即在組件服務程序中尋找到類對象,再調用其中的方法創建一個對象,並通過QueryInterFace返回一個接口指針給客戶使用;如果沒被激活,就需要先在注冊表中尋找到與CLSID相對應的執行程序地址,在SCM的幫助下裝載服務器程序,然後再尋找類對象返回接口指針。采集我?yuXvv
為了解除客戶與對象的並發性和重入限制之間的關系的模型,建立對象與進程和線程之間相互關系的模型,出現了套間這個概念。一個套間可