① 什麼是資料庫技術
資料庫技術是信息系統的一個核心技術。是一種計算機輔助管理數據的方法,它研究如何組織和存儲數據,如何高效地獲取和處理數據。是通過研究資料庫的結構、存儲、設計、管理以及應用的基本理論和實現方法,並利用這些理論來實現對資料庫中的數據進行處理、分析和理解的技術。即:資料庫技術是研究、管理和應用資料庫的一門軟體科學。 資料庫技術是現代信息科學與技術的重要組成部分,是計算機數據處理與信息管理系統的核心。資料庫技術研究和解決了計算機信息處理過程中大量數據有效地組織和存儲的問題,在資料庫系統中減少數據存儲冗餘、實現數據共享、保障數據安全以及高效地檢索數據和處理數據。 資料庫技術研究和管理的對象是數據,所以資料庫技術所涉及的具體內容主要包括:通過對數據的統一組織和管理,按照指定的結構建立相應的資料庫和數據倉庫;利用資料庫管理系統和數據挖掘系統設計出能夠實現對資料庫中的數據進行添加、修改、刪除、處理、分析、理解、報表和列印等多種功能的數據管理和數據挖掘應用系統;並利用應用管理系統最終實現對數據的處理、分析和理解。
詳情請參考: http://ke..com/view/500320.htm
② 為什麼要對資料庫進行重組和重構
簡單來說,資料庫運行時間長後會產生一定的垃圾,影響運行速度,尤其是一些超大的資料庫。
重構資料庫後會把這些垃圾過濾掉。
③ 資料庫是什麼意思
★資料庫發展階段大致劃分為如下幾個階段:
人工管理階段;
文件系統階段;
資料庫系統階段;
高級資料庫階段。
當人們從不同的角度來描述這一概念時就有不同的定義(當然是描述性的)。例如,稱資料庫是一個「記錄保存系統」(該定義強調了資料庫是若干記錄的集合)。又如稱資料庫是「人們為解決特定的任務,以一定的組織方式存儲在一起的相關的數據的集合」(該定義側重於數據的組織)。更有甚者稱資料庫是「一個數據倉庫」。當然,這種說法雖然形象,但並不嚴謹。
嚴格地說,資料庫是「按照數據結構來組織、存儲和管理數據的倉庫」。在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣「倉庫」,並根據管理的需要進行相應的處理。例如,企業或事業單位的人事部門常常要把本單位職工的基本情況(職工號、姓名、年齡、性別、籍貫、工資、簡歷等)存放在表中,這張表就可以看成是一個資料庫。有了這個"數據倉庫"我們就可以根據需要隨時查詢某職工的基本情況,也可以查詢工資在某個范圍內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
J.Martin給資料庫下了一個比較完整的定義:資料庫是存儲在一起的相關數據的集合,這些數據是結構化的,無有害的或不必要的冗餘,並為多種應用服務;數據的存儲獨立於使用它的程序;對資料庫插入新數據,修改和檢索原有數據均能按一種公用的和可控制的方式進行。當某個系統中存在結構上完全分開的若干個資料庫時,則該系統包含一個「資料庫集合」。
· 資料庫的優點
使用資料庫可以帶來許多好處:如減少了數據的冗餘度,從而大大地節省了數據的存儲空間;實現數據資源的充分共享等等。此外,資料庫技術還為用戶提供了非常簡便的使用手段使用戶易於編寫有關資料庫應用程序。特別是近年來推出的微型計算機關系資料庫管理系統dBASELL,操作直觀,使用靈活,編程方便,環境適應廣泛(一般的十六位機,如IBM/PC/XT,國產長城0520等均可運行種軟體),數據處理能力極強。資料庫在我國正得到愈來愈廣泛的應用,必將成為經濟管理的有力工具。
資料庫是通過資料庫管理系統(DBMS-DATA BASE MANAGEMENT SYSTEM)軟體來實現數據的存儲、管理與使用的dBASELL就是一種資料庫管理系統軟體。
· 資料庫結構與資料庫種類
資料庫通常分為層次式資料庫、網路式資料庫和關系式資料庫三種。而不同的資料庫是按不同的數據結構來聯系和組織的。
1.數據結構模型
(1)數據結構
所謂數據結構是指數據的組織形式或數據之間的聯系。如果用D表示數據,用R表示數據對象之間存在的關系集合,則將DS=(D,R)稱為數據結構。例如,設有一個電話號碼簿,它記錄了n個人的名字和相應的電話號碼。為了方便地查找某人的電話號碼,將人名和號碼按字典順序排列,並在名字的後面跟隨著對應的電話號碼。這樣,若要查找某人的電話號碼(假定他的名字的第一個字母是Y),那麼只須查找以Y開頭的那些名字就可以了。該例中,數據的集合D就是人名和電話號碼,它們之間的聯系R就是按字典順序的排列,其相應的數據結構就是DS=(D,R),即一個數組。(2)數據結構種類
數據結構又分為數據的邏輯結構和數據的物理結構。數據的邏輯結構是從邏輯的角度(即數據間的聯系和組織方式)來觀察數據,分析數據,與數據的存儲位置無關。數據的物理結構是指數據在計算機中存放的結構,即數據的邏輯結構在計算機中的實現形式,所以物理結構也被稱為存儲結構。本節只研究數據的邏輯結構,並將反映和實現數據聯系的方法稱為數據模型。
目前,比較流行的數據模型有三種,即按圖論理論建立的層次結構模型和網狀結構模型以及按關系理論建立的關系結構模型。
2.層次、網狀和關系資料庫系統
(1)層次結構模型
層次結構模型實質上是一種有根結點的定向有序樹(在數學中"樹"被定義為一個無回的連通圖)。例如圖20.6.4是一個高等學校的組織結構圖。這個組織結構圖像一棵樹,校部就是樹根(稱為根結點),各系、專業、教師、學生等為枝點(稱為結點),樹根與枝點之間的聯系稱為邊,樹根與邊之比為1:N,即樹根只有一個,樹枝有N個。這種數據結構模型的一般結構見圖20.6.5所示。
圖20.6.4 高等學校的組織結構圖 圖20.6.5 層次結構模型
圖20.6.5中,Ri(i=1,2,…6)代表記錄(即數據的集合),其中R1就是根結點(如果Ri看成是一個家族,則R1就是祖先,它是R2、R3、R4的雙親,而R2、R3、R4互為兄弟),R5、R6也是兄弟,且其雙親為R3。R2、R4、R5、R6又被稱為葉結點(即無子女的結點)。這樣,Ri(i=1,2,…6)就組成了以R1為樹根的一棵樹,這就是一個層次數據結構模型。
按照層次模型建立的資料庫系統稱為層次模型資料庫系統。IMS(Information Manage-mentSystem)是其典型代表。
(2)網狀結構模型
在圖20.6.6中,給出了某醫院醫生、病房和病人之間的聯系。即每個醫生負責治療三個病人,每個病房可住一到四個病人。如果將醫生看成是一個數據集合,病人和病房分別是另外兩個數據集合,那麼醫生、病人和病房的比例關系就是M:N:P(即M個醫生,N個病人,P間病房)。這種數據結構就是網狀數據結構,它的一般結構模型如圖20.6.7所示。在圖中,記錄Ri(i=1,2,8)滿足以下條件:
①可以有一個以上的結點無雙親(如R1、R2、R3)。
②至少有一個結點有多於一個以上的雙親。在"醫生、病人、病房"例中,"醫生集合有若干個結點(M個醫生結點)無"雙親",而"病房"集合有P個結點(即病房),並有一個以上的"雙親"(即病人)。
圖20.6.6 醫生、病房和病人之間的關系
圖20.6.7 網狀結構模型
按照網狀數據結構建立的資料庫系統稱為網狀資料庫系統,其典型代表是DBTG(Data Base Task Group)。用數學方法可將網狀數據結構轉化為層次數據結構。
(3)關系結構模型
關系式數據結構把一些復雜的數據結構歸結為簡單的二元關系(即二維表格形式)。例如某單位的職工關系就是一個二元關系(見表20.6.8)。這個四行六列的表格的每一列稱為一個欄位(即屬性),欄位名相當於標題欄中的標題(屬性名稱);表的每一行是包含了六個屬性(工號、姓名、年齡、性別、職務、工資)的一個六元組,即一個人的記錄。這個表格清晰地反映出該單位職工的基本情況。
表20.6.8 職工基本情況
通常一個m行、n列的二維表格的結構如表20.6.9所示。
表中每一行表示一個記錄值,每一列表示一個屬性(即欄位或數據項)。該表一共有m個記錄。每個記錄包含n個屬性。
作為一個關系的二維表,必須滿足以下條件:
(1)表中每一列必須是基本數據項(即不可再分解)。(2)表中每一列必須具有相同的數據類型(例如字元型或數值型)。(3)表中每一列的名字必須是唯一的。(4)表中不應有內容完全相同的行。(5)行的順序與列的順序不影響表格中所表示的信息的含義。
由關系數據結構組成的資料庫系統被稱為關系資料庫系統。
在關系資料庫中,對數據的操作幾乎全部建立在一個或多個關系表格上,通過對這些關系表格的分類、合並、連接或選取等運算來實現數據的管理。dBASEII就是這類資料庫管理系統的典型代表。對於一個實際的應用問題(如人事管理問題),有時需要多個關系才能實現。用dBASEII建立起來的一個關系稱為一個資料庫(或稱資料庫文件),而把對應多個關系建立起來的多個資料庫稱為資料庫系統。dBASEII的另一個重要功能是通過建立命令文件來實現對資料庫的使用和管理,對於一個資料庫系統相應的命令序列文件,稱為該資料庫的應用系統。因此,可以概括地說,一個關系稱為一個資料庫,若干個資料庫可以構成一個資料庫系統。資料庫系統可以派生出各種不同類型的輔助文件和建立它的應用系統。
· 資料庫的要求與特性
為了使各種類型的資料庫系統能夠充分發揮它們的優越性,必須對資料庫管理系統的使用提出一些明確的要求。
1.建立資料庫文件的要求
(1)盡量減少數據的重復,使數據具有最小的冗餘度。計算機早期應用中的文件管理系統,由於數據文件是用戶各自建立的,幾個用戶即使有許多相同的數據也得放在各自的文件中,因而造成存儲的數據大量重復,浪費存儲空間。資料庫技術正是為了克服這一缺點而出現的,所以在組織數據的存儲時應避免出現冗餘。
(2)提高數據的利用率,使眾多用戶都能共享數據資源。
(3)注意保持數據的完整性。這對某些需要歷史數據來進行預測、決策的部門(如統計局、銀行等)特別重要。
(4)注意同一數據描述方法的一致性,使數據操作不致發生混亂。如一個人的學歷在人事檔案中是大學畢業,而在科技檔案中卻是大學程度,這樣就容易造成混亂。
(5)對於某些需要保密的數據,必須增設保密措施。
(6)數據的查找率高,根據需要數據應能被及時維護。
2.資料庫文件的特徵
無論使用哪一種資料庫管理系統,由它們所建立的資料庫文件都可以看成是具有相同性質的記錄的集合,因而這些資料庫文件都有相同的特性:
(1)文件的記錄格式相同,長度相等。
(2)不同的行是不同的記錄,因而具有不同的內容。
(3)不同的列表示不同的欄位名,同一列中的數據的性質(屬性)相同。
(4)每一行各列的內容是不能分割的,但行的順序和列的順序不影響文件內容的表達。
3.文件的分類
對文件引用最多的是主文件和事物文件。其他的文件分類還包括表文件、備份文件、檔案的輸出文件等。下面將講述這些文件。
(1)主文件。主文件是某特定應用領域的永久性的數據資源。主文件包含那些被定期存取以提供信息和經常更新以反映最新狀態的記錄。典型的主文件有庫存文件、職工主文件和收帳主文件等。
(2)事務文件。事務文件包含著作為一個信息系統的數據活動(事務)的那些記錄。這些事務被分批以構成事務文件。例如,從每周工資卡上錄制下來的數分批存放在一個事務文件上,然後對照工資清單文件進行處理以便列印出工資支票和工資記錄簿。
(3)表文件。表文件是一些表格。之所以單獨建立表文件而不把表設計在程序中是為了便於修改。例如,一個公用事業公司的稅率表或國內稅務局的稅率就可以存儲在表中文件。
(4)備用文件。備用文件是現有生產性文件的一個復製品。一旦生產性文件受到破壞,利用備用文件就可以重新建立生產性文件。
(5)檔案文件。檔案文件不是提供當前處理使用的,而是保存起來作為歷史參照的。例如,國內稅務局(IRS)可能要求檢查某個人最近15年的歷史。實際上,檔案文件恰恰是在給定時間內工作的一個"快照"。
(6)輸出文件。輸出文件包含將要列印在列印機上的、顯在屏幕上的或者繪制在繪圖儀上的那些信息的數值映象。輸出文件可以是"假離線的"(存儲在輔存設備上),當輸出設備可用時才進行實際的輸出。
④ 什麼是資料庫技術
資料庫技術就是存儲、處理、管理數據的一門計算機技術,是計算機科學技術中發展最快、應用最為廣泛的重要分支之一,是計算機信息系統的重要技術基礎和支柱。資料庫是存儲在計算機內的有結構的數據集合,資料庫系統是指由硬體設備、軟體系統、專業領域的資料庫和資料庫管理人員構成的一個運行系統。
資料庫技術產生於20世紀60年代末70年代初。隨著計算機技術和相應技術領域的發展,資料庫技術得到了極大的發展,如面向對象資料庫技術、多媒體資料庫技術、Web資料庫技術、數據挖掘技術、空間數據存儲技術等。
⑤ ps5重構資料庫有什麼用
可以恢復因為非法關機等原因造成系統文件損壞無法正常啟動
ps5重建資料庫是指如果玩游戲遇到經常死機報錯什麼的奇怪現象,而又不是游戲的問題時,可以重組資料庫解決。
⑥ 資料庫重構技術是什麼
主要是指資料庫運行很長時間後,物理結構、邏輯結構等都發生了變化
導致性能低下,這時候需要重構資料庫
重構的價值是毋庸置疑的,這已在許多項目中證明了。重構能幫助軟體專業人士改進系統設計及其可維護性、可擴展性和性能。本書首次介紹了專門針對資料庫系統設計的強大的重構技術。
⑦ 資料庫-架構和資料庫-管理指的是什麼
資料庫架構:
下面是基於sqlserver資料庫來談的。
SQLServer經過這些年的發展,其實已經有很多很好的技術可以使用,如Replication、SSB、Cluster、Mirroring等(可以參考我在SQLServer DBA 三十問和SQLServer 高可用、高性能和高保護延伸 中的一些技術方面的知識),而且這些技術在可靠性方面已經通過了市場的認可,有很多公司在為提高其程序的可靠性、安全性和高效性等方面或多或少的採用了其中的某些技術,以下就我接觸過的這些技術方面的應用,主要針對網站這種流量很大,讀多寫少的應用,就資料庫架構方面做些探討,希望對各位有所幫助,如有不對的地方,歡迎大家指正和交流。
資料庫架構需要考慮的問題:
數據可靠和一致性;
數據容災;
當數據量和訪問壓力變大時,方便擴充;
高度可用,出問題時能及時恢復,無單點故障;
不應因為某一台機器出現問題,導致整網性能的急劇下降;
方便維護。
資料庫管理:
資料庫管理(Database Manager)是有關建立、存儲、修改和存取資料庫中信息的技術,是指為保證資料庫系統的正常運行和服務質量,有關人員須進行的技術管理工作。負責這些技術管理工作的個人或集體稱為資料庫管理員(DBA)。資料庫管理的主要內容有:資料庫的調優、資料庫的重組、資料庫的重構、資料庫的安全管控、報錯問題的分析和匯總和處理、資料庫數據的日常備份. 資料庫的建立:資料庫的設計只是提供了數據的類型、邏輯結構、聯系、約束和存儲結構等有關數據的描述。這些描述稱為數據模式。
⑧ 請問資料庫是什麼意思詳細些!
資料庫,顧名思義,是存入數據的倉庫。只不過這個倉庫是在計算機存儲設備上的,而且數據是按一定格式存放的。
當人們收集了大量的數據後,應該把它們保存起來進入近一步的處理,進一步的抽取有用的信息。當年人們把數據存放在文件櫃中,可現在隨著社會的發展,數據量急劇增長,現在人們就藉助計算機和資料庫技術科學的保存大量的數據,以便能更好的利用這些數據資源。
要是下定義的話,就應該是:指長期儲存在計算機內的、有組織的、可共享的數據集合。
資料庫包含關系資料庫、面向對象資料庫及新興的XML資料庫等多種,目前應用最廣泛的是關系資料庫,若在關系資料庫基礎上提供部分面向對象資料庫功能的對象關系資料庫。在資料庫技術的早期還曾經流行過層次資料庫與網狀資料庫,但這兩類資料庫目前已經極少使用。
資料庫管理
資料庫管理(Database Administration)是有關建立、存儲、修改和存取資料庫中信息的技術,是指為保證資料庫系統的正常運行和服務質量,有關人員須進行的技術管理工作。負責這些技術管理工作的個人或集體稱為資料庫管理員(DBA)。資料庫管理的主要內容有:資料庫的建立、資料庫的調整、資料庫的重組、資料庫的重構、資料庫的安全控制、數據的完整性控制和對用戶提供技術支持。
資料庫的建立:資料庫的設計只是提供了數據的類型、邏輯結構、聯系、約束和存儲結構等有關數據的描述。這些描述稱為數據模式。要建立可運行的資料庫,還需進行下列工作:
(1)選定資料庫的各種參數,例如最大的數據存儲空間、緩沖決的數量、並發度等。這些參數可以由用戶設置,也可以由系統按默認值設置。
(2)定義資料庫,利用資料庫管理系統(DBMS)所提供的數據定義語言和命令,定義資料庫名、數據模式、索引等。
(3)准備和裝入數據,定義資料庫僅僅建立了資料庫的框架,要建成資料庫還必須裝入大量的數據,這是一項浩繁的工作。在數據的准備和錄入過程中,必須在技術和制度上採取措施,保證裝入數據的正確性。計算機系統中原已積累的數據,要充分利用,盡可能轉換成資料庫的數據。
注: "資料庫"這個詞對於不同的人應該給予不同的感覺。如果你是一個最終用戶,你根本就不關心數據存儲和維護的細節,資料庫也不應該拿這些事情來煩你。但是如果你是一個資料庫管理員,那麼有些細節上的東西你就必須要清楚。資料庫管理系統可以為不同的用戶提供不同的視圖,也就是他們所看到的資料庫是不一樣的。這就需要進行數據抽象,以形成這些不同的視圖。
最早是在CODASYL的DBTG報告中完整地給出了數據抽象的三個層次。ANSI/SPARC報告中也提出了類似的建議,這個報告中抽象的層次為內部層、概念層和外部層。但是,現在的資料庫管理系統是根據DBTG的報告從三個層次來進行抽象的,它們分別是物理層、邏輯層和視圖層(概念層)。
資料庫的種類
大型資料庫有:Oracle、Sybase、DB2、SQL server
小型資料庫有:Access、MySQL、BD2等。
⑨ 代碼重構的概述
重構(),通過調整程序代碼改善軟體的質量、性能,使其程序的設計模式和架構更趨合理,提高軟體的擴展性和維護性。也許有人會問,為什麼不在項目開始時多花些時間把設計做好,而要以後花時間來重構呢?要知道一個完美得可以預見未來任何變化的設計,或一個靈活得可以容納任何擴展的設計是不存在的。系統設計人員對即將著手的項目往往只能從大方向予以把控,而無法知道每個細枝末節,其次永遠不變的就是變化,提出需求的用戶往往要在軟體成型後,才開始品頭論足,系統設計人員畢竟不是先知先覺的神仙,功能的變化導致設計的調整再所難免。所以測試為先,持續重構作為良好開發習慣被越來越多的人所採納,測試和重構像黃河的護堤,成為保證軟體質量的法寶。 在不改變系統功能的情況下,改變系統的實現方式。為什麼要這么做?投入精力不用來滿足客戶關心的需求,而是僅僅改變了軟體的實現方式,這是否是在浪費客戶的投資呢?
重構的重要性要從軟體的生命周期說起。軟體不同與普通的產品,他是一種智力產品,沒有具體的物理形態。一個軟體不可能發生物理損耗,界面上的按鈕永遠不會因為按動次數太多而發生接觸不良。那麼為什麼一個軟體製造出來以後,卻不能永遠使用下去呢?
對軟體的生命造成威脅的因素只有一個:需求的變更。一個軟體總是為解決某種特定的需求而產生,時代在發展,客戶的業務也在發生變化。有的需求相對穩定一些,有的需求變化的比較劇烈,還有的需求已經消失了,或者轉化成了別的需求。在這種情況下,軟體必須相應的改變。
考慮到成本和時間等因素,當然不是所有的需求變化都要在軟體系統中實現。但是總的說來,軟體要適應需求的變化,以保持自己的生命力。
這就產生了一種糟糕的現象:軟體產品最初製造出來,是經過精心的設計,具有良好架構的。但是隨著時間的發展、需求的變化,必須不斷的修改原有的功能、追加新的功能,還免不了有一些缺陷需要修改。為了實現變更,不可避免的要違反最初的設計構架。經過一段時間以後,軟體的架構就千瘡百孔了。bug越來越多,越來越難維護,新的需求越來越難實現,軟體的構架對新的需求漸漸的失去支持能力,而是成為一種制約。最後新需求的開發成本會超過開發一個新的軟體的成本,這就是這個軟體系統的生命走到盡頭的時候。
重構就能夠最大限度的避免這樣一種現象。系統發展到一定階段後,使用重構的方式,不改變系統的外部功能,只對內部的結構進行重新的整理。通過重構,不斷的調整系統的結構,使系統對於需求的變更始終具有較強的適應能力。
通過重構可以達到以下的目標:
·持續糾偏和改進軟體設計
重構和設計是相輔相成的,它和設計彼此互補。有了重構,你仍然必須做預先的設計,但是不必是最優的設計,只需要一個合理的解決方案就夠了,如果沒有重構、程序設計會逐漸腐敗變質,愈來愈像斷線的風箏,脫韁的野馬無法控制。重構其實就是整理代碼,讓所有帶著發散傾向的代碼回歸本位。
·
Martin Flower在《重構》中有一句經典的話:任何一個傻瓜都能寫出計算機可以理解的程序,只有寫出人類容易理解的程序才是優秀的程序員。對此,筆者感觸很深,有些程序員總是能夠快速編寫出可運行的代碼,但代碼中晦澀的命名使人暈眩得需要緊握坐椅扶手,試想一個新兵到來接手這樣的代碼他會不會想當逃兵呢?
軟體的生命周期往往需要多批程序員來維護,我們往往忽略了這些後來人。為了使代碼容易被他人理解,需要在實現軟體功能時做許多額外的事件,如清晰的排版布局,簡明扼要的注釋,其中命名也是一個重要的方面。一個很好的辦法就是採用暗喻命名,即以對象實現的功能的依據,用形象化或擬人化的手法進行命名,一個很好的態度就是將每個代碼元素像新生兒一樣命名,也許筆者有點命名偏執狂的傾向,如能榮此雅號,將深以此為幸。
對於那些讓人充滿迷茫感甚至誤導性的命名,需要果決地、大刀闊斧地整容,永遠不要手下留情!
·幫助發現隱藏的代碼缺陷
孔子說過:溫故而知新。重構代碼時逼迫你加深理解原先所寫的代碼。筆者常有寫下程序後,卻發生對自己的程序邏輯不甚理解的情景,曾為此驚悚過,後來發現這種症狀居然是許多程序員常患的感冒。當你也發生這樣的情形時,通過重構代碼可以加深對原設計的理解,發現其中的問題和隱患,構建出更好的代碼。
·從長遠來看,有助於提高編程效率
當你發現解決一個問題變得異常復雜時,往往不是問題本身造成的,而是你用錯了方法,拙劣的設計往往導致臃腫的編碼。
改善設計、提高可讀性、減少缺陷都是為了穩住陣腳。良好的設計是成功的一半,停下來通過重構改進設計,或許會在當前減緩速度,但它帶來的後發優勢卻是不可低估的。 新官上任三把火,開始一個全新??、腳不停蹄、加班加點,一支聲勢浩大的千軍萬碼夾裹著程序員激情和扣擊鍵盤的鳴金奮力前行,勢如破竹,攻城掠地,直指黃龍府。
開發經理是這支浩浩湯湯代碼隊伍的統帥,他負責這支隊伍的命運,當齊桓公站在山頂上看到管仲訓練的隊伍整齊劃一地前進時,他感嘆說我有這樣一支軍隊哪裡還怕沒有勝利呢?。但很遺憾,你手中的這支隊伍原本只是散兵游勇,在前進中招兵買馬,不斷壯大,所以隊伍變形在所難免。當開發經理發覺隊伍變形時,也許就是克制住攻克前方山頭的誘惑,停下腳步整頓隊伍的時候了。
Kent Beck提出了代碼壞味道的說法,和我們所提出的隊伍變形是同樣的意思,隊伍變形的信號是什麼呢?以下列述的代碼症狀就是隊伍變形的強烈信號:
·代碼中存在重復的代碼
中國有118 家整車生產企業,數量幾乎等於美、日、歐所有汽車廠家數之和,但是全國的年產量卻不及一個外國大汽車公司的產量。重復建設只會導致效率的低效和資源的浪費。
程序代碼更是不能搞重復建設,如果同一個類中有相同的代碼塊,請把它提煉成類的一個獨立方法,如果不同類中具有相同的代碼,請把它提煉成一個新類,永遠不要重復代碼。
·過大的類和過長的方法
過大的類往往是類抽象不合理的結果,類抽象不合理將降低了代碼的復用率。方法是類王國中的諸侯國,諸侯國太大勢必動搖中央集權。過長的方法由於包含的邏輯過於復雜,錯誤機率將直線上升,而可讀性則直線下降,類的健壯性很容易被打破。當看到一個過長的方法時,需要想辦法將其劃分為多個小方法,以便於分而治之。
·牽一毛而需要動全身的修改
當你發現修改一個小功能,或增加一個小功能時,就引發一次代碼地震,也許是你的設計抽象度不夠理想,功能代碼太過分散所引起的。
·類之間需要過多的通訊
A類需要調用B類的過多方法訪問B的內部數據,在關繫上這兩個類顯得有點狎昵,可能這兩個類本應該在一起,而不應該分家。
·過度耦合的信息鏈
計算機是這樣一門科學,它相信可以通過添加一個中間層解決任何問題,所以往往中間層會被過多地追加到程序中。如果你在代碼中看到需要獲取一個信息,需要一個類的方法調用另一個類的方法,層層掛接,就象輸油管一樣節節相連。這往往是因為銜接層太多造成的,需要查看就否有可移除的中間層,或是否可以提供更直接的調用方法。
·各立山頭幹革命
如果你發現有兩個類或兩個方法雖然命名不同但卻擁有相似或相同的功能,你會發現往往是因為開發團隊協調不夠造成的。筆者曾經寫了一個頗好用的字元串處理類,但因為沒有及時通告團隊其他人員,後來發現項目中居然有三個字元串處理類。革命資源是珍貴的,我們不應各立山頭幹革命。
·不完美的設計
在筆者剛完成的一個比對報警項目中,曾安排阿朱開發報警模塊,即通過Socket向指定的簡訊平台、語音平台及客戶端報警器插件發送報警報文信息,阿朱出色地完成了這項任務。後來用戶又提出了實時比對的需求,即要求第三方系統以報文形式向比對報警系統發送請求,比對報警系統接收並響應這個請求。這又需要用到Socket報文通訊,由於原來的設計沒有將報文通訊模塊獨立出來,所以無法復用阿朱開發的代碼。後來我及時調整了這個設計,新增了一個報文收發模塊,使系統所有的對外通訊都復用這個模塊,系統的整體設計也顯得更加合理。
每個系統都或多或少存在不完美的設計,剛開始可能注意不到,到後來才會慢慢凸顯出來,此時唯有勇於更改才是最好的出路。
·缺少必要的注釋
雖然許多軟體工程的書籍常提醒程序員需要防止過多注釋,但這個擔心好象並沒有什麼必要。往往程序員更感興趣的是功能實現而非代碼注釋,因為前者更能帶來成就感,所以代碼注釋往往不是過多而是過少,過於簡單。人的記憶曲線下降的坡度是陡得嚇人的,當過了一段時間後再回頭補注釋時,很容易發生提筆忘字,愈言且止的情形。
曾在網上看到過微軟的代碼注釋,其詳盡程度讓人嘆為觀止,也從中體悟到了微軟成功的一個經驗。 學習一種可以大幅提高生產力的新技術時,你總是難以察覺其不適用的場合。通常你在一個特定場景中學習它,這個場景往往是個項目。這種情況下你很難看出什麼會造成這種新技術成效不彰或甚至形成危害。十年前,對象技術(object tech.)的情況也是如此。那時如果有人問我「何時不要使用對象」,我很難回答。並非我認為對象十全十美、沒有局限性 — 我最反對這種盲目態度,而是盡管我知道它的好處,但確實不知道其局限性在哪兒。
現在,重構的處境也是如此。我們知道重構的好處,我們知道重構可以給我們的工作帶來垂手可得的改變。但是我們還沒有獲得足夠的經驗,我們還看不到它的局限性。
這一小節比我希望的要短。暫且如此吧。隨著更多人學會重構技巧,我們也將對??你應該嘗試一下重構,獲得它所提供的利益,但在此同時,你也應該時時監控其過程,注意尋找重構可能引入的問題。請讓我們知道你所遭遇的問題。隨著對重構的了解日益增多,我們將找出更多解決辦法,並清楚知道哪些問題是真正難以解決的。
·資料庫(Databases)
「重構」經常出問題的一個領域就是資料庫。絕大多數商用程序都與它們背後的database schema(資料庫表格結構)緊密耦合(coupled)在一起,這也是database schema如此難以修改的原因之一。另一個原因是數據遷移(migration)。就算你非常小心地將系統分層(layered),將database schema和對象模型(object model)間的依賴降至最低,但database schema的改變還是讓你不得不遷移所有數據,這可能是件漫長而煩瑣的工作。
在「非對象資料庫」(nonobject databases)中,解決這個問題的辦法之一就是:在對象模型(object model)和資料庫模型(database model)之間插入一個分隔層(separate layer),這就可以隔離兩個模型各自的變化。升級某一模型時無需同時升級另一模型,只需升級上述的分隔層即可。這樣的分隔層會增加系統復雜度,但可以給你很大的靈活度。如果你同時擁有多個資料庫,或如果資料庫模型較為復雜使你難以控制,那麼即使不進行重構,這分隔層也是很重要的。
你無需一開始就插入分隔層,可以在發現對象模型變得不穩定時再產生它。這樣你就可以為你的改變找到最好的杠桿效應。
對開發者而言,對象資料庫既有幫助也有妨礙。某些面向對象資料庫提供不同版本的對象之間的自動遷移功能,這減少了數據遷移時的工作量,但還是會損失一定時間。如果各資料庫之間的數據遷移並非自動進行,你就必須自行完成遷移工作,這個工作量可是很大的。這種情況下你必須更加留神classes內的數據結構變化。你仍然可以放心將classes的行為轉移過去,但轉移值域(field)時就必須格外小心。數據尚未被轉移前你就得先運用訪問函數(accessors)造成「數據已經轉移」的假象。一旦你確定知道「數據應該在何處」時,就可以一次性地將數據遷移過去。這時惟一需要修改的只有訪問函數(accessors),這也降低了錯誤風險。
·修改介面(Changing Interfaces)
關於對象,另一件重要事情是:它們允許你分開修改軟體模塊的實現(implementation)和介面(interface)。你可以安全地修改某對象內部而不影響他人,但對於介面要特別謹慎 — 如果介面被修改了,任何事情都有可能發生。
一直對重構帶來困擾的一件事就是:許多重構手法的確會修改介面。像Rename Method(273)這么簡單的重構手法所做的一切就是修改介面。這對極為珍貴的封裝概念會帶來什麼影響呢?
如果某個函數的所有調用動作都在你的控制之下,那麼即使修改函數名稱也不會有任何問題。哪怕面對一個public函數,只要能取得並修改其所有調用者,你也可以安心地將這個函數易名。只有當需要修改的介面系被那些「找不到,即使找到也不能修改」的代碼使用時,介面的修改才會成為問題。如果情況真是如此,我就會說:這個介面是個「已發布介面」(published interface)— 比公開介面(public interface)更進一步。介面一旦發行,你就再也無法僅僅修改調用者而能夠安全地修改介面了。你需要一個略為復雜的程序。
這個想法改變了我們的問題。如今的問題是:該如何面對那些必須修改「已發布介面」的重構手法?
簡言之,如果重構手法改變了已發布介面(published interface),你必須同時維護新舊兩個介面,直到你的所有用戶都有時間對這個變化做出反應。幸運的是這不太困難。你通常都有辦法把事情組織好,讓舊介面繼續工作。請盡量這么做:讓舊介面調用新介面。當你要修改某個函數名稱時,請留下舊函數,讓它調用新函數。千萬不要拷貝函數實現碼,那會讓你陷入「重復代碼」(plicated code)的泥淖中難以自拔。你還應該使用Java提供的 deprecation(反對)設施,將舊介面標記為 deprecated。這么一來你的調用者就會注意到它了。
這個過程的一個好例子就是Java容器類(collection classes)。Java 2的新容器取代了原先一些容器。當Java 2容器發布時,JavaSoft花了很大力氣來為開發者提供一條順利遷徙之路。
「保留舊介面」的辦法通常可行,但很煩人。起碼在一段時間里你必須建造(build)並維護一些額外的函數。它們會使介面變得復雜,使介面難以使用。還好我們有另一個選擇:不要發布(publish)介面。當然我不是說要完全禁止,因為很明顯你必得發布一些介面。如果你正在建造供外部使用的APIs,像Sun所做的那樣,肯定你必得發布介面。我之所以說盡量不要發布,是因為我常常看到一些開發團隊公開了太多介面。我曾經看到一支三人團隊這么工作:每個人都向另外兩人公開發布介面。這使他們不得不經常來回維護介面,而其實他們原本可以直接進入程序庫,徑行修改自己管理的那一部分,那會輕松許多。過度強調「代碼擁有權」的團隊常常會犯這種錯誤。發布介面很有用,但也有代價。所以除非真有必要,別發布介面。這可能意味需要改變你的代碼擁有權觀念,讓每個人都可以修改別人的代碼,以運應介面的改動。以搭檔(成對)編程(Pair Programming)完成這一切通常是個好主意。
不要過早發布(published)介面。請修改你的代碼擁有權政策,使重構更順暢。
Java之中還有一個特別關於「修改介面」的問題:在throws子句中增加一個異常。這並不是對簽名式(signature)的修改,所以你無法以delegation(委託手法)隱藏它。但如果用戶代碼不作出相應修改,編譯器不會讓它通過。這個問題很難解決。你可以為這個函數選擇一個新名tion(可控式異常)轉換成一個unchecked exception(不可控異常)。你也可以拋出一個unchecked異常,不過這樣你就會失去檢驗能力。如果你那麼做,你可以警告調用者:這個unchecked異常日後會變成一個checked異常。這樣他們就有時間在自己的代碼中加上對此異常的處理。出於這個原因,我總是喜歡為整個package定義一個superclass異常(就像java.sql的SQLException),並確保所有public函數只在自己的throws子句中聲明這個異常。這樣我就可以隨心所欲地定義subclass異常,不會影響調用者,因為調用者永遠只知道那個更具一般性的superclass異常。
·難以通過重構手法完成的設計改動
通過重構,可以排除所有設計錯誤嗎?是否存在某些核心設計決策,無法以重構手法修改?在這個領域里,我們的統計數據尚不完整。當然某些情況下我們可以很有效地重構,這常常令我們倍感驚訝,但的確也有難以重構的地方。比如說在一個項目中,我們很難(但還是有可能)將「無安全需求(no security requirements)情況下構造起來的系統」重構為「安全性良好的(good security)系統」。
這種情況下我的辦法就是「先想像重構的情況」。考慮候選設計方案時,我會問自己:將某個設計重構為另一個設計的難度有多大?如果看上去很簡單,我就不必太擔心選擇是否得當,於是我就會選最簡單的設計,哪怕它不能覆蓋所有潛在需求也沒關系。但如果預先看不到簡單的重構辦法,我就會在設計上投入更多力氣。不過我發現,這種情況很少出現。
·何時不該重構?
有時候你根本不應該重構 — 例如當你應該重新編寫所有代碼的時候。有時候既有代碼實在太混亂,重構它還不如從新寫一個來得簡單。作出這種決定很困難,我承認我也沒有什麼好准則可以判斷何時應該放棄重構。
重寫(而非重構)的一個清楚訊號就是:現有代碼根本不能正常運作。你可能只是試著做點測試,然後就發現代碼中滿是錯誤,根本無法穩定運作。記住,重構之前,代碼必須起碼能夠在大部分情況下正常運作。
一個折衷辦法就是:將「大塊頭軟體」重構為「封裝良好的小型組件」。然後你就可以逐一對組件作出「重構或重建」的決定。這是一個頗具希望的辦法,但我還沒有足夠數據,所以也無法寫出優秀的指導原則。對於一個重要的古老系統,這肯定會是一個很好的方向。
另外,如果項目已近最後期限,你也應該避免重構。在此時機,從重構過程贏得的生產力只有在最後期限過後才能體現出來,而那個時候已經時不我予。Ward Cunningham對此有一個很好的看法。他把未完成的重構工作形容為「債務」。很多公司都需要借債來使自己更有效地運轉。但是借債就得付利息,過於復雜的代碼所造成的「維護和擴展的額外開銷」就是利息。你可以承受一定程度的利息,但如果利息太高你就會被壓垮。把債務管理好是很重要的,你應該隨時通過重構來償還一部分債務。
如果項目已經非常接近最後期限,你不應該再分心於重構,因為已經沒有時間了。不過多個項目經驗顯示:重構的確能夠提高生產力。如果最後你沒有足夠時間,通常就表示你其實早該進行重構。 「重構」肩負一項特別任務:它和設計彼此互補。初學編程的時候,我埋頭就寫程序,渾渾噩噩地進行開發。然而很快我便發現,「事先設計」(upfront design)可以助我節省回頭工的高昂成本。於是我很快加強這種「預先設計」風格。許多人都把設計看作軟體開發的關鍵環節,而把編程(programming)看作只是機械式的低級勞動。他們認為設計就像畫工程圖而編碼就像施工。但是你要知道,軟體和真實器械有著很大的差異。軟體的可塑性更強,而且完全是思想產品。正如Alistair Cockburn所說:『有了設計,我可以思考更快,但是其中充滿小漏洞。』
有一種觀點認為:重構可以成為「預先設計」的替代品。這意思是你根本不必做任何設計,只管按照最初想法開始編碼,讓代碼有效運作,然後再將它重構成型。事實上這種辦法真的可行。我的確看過有人這么做,最後獲得設計良好的軟體。極限編程(Extreme Programming)【Beck, XP】 的支持者極力提倡這種辦法。
盡管如上所言,只運用重構也能收到效果,但這並不是最有效的途徑。是的,即使極限編程(Extreme Programming)愛好者也會進行預先設計。他們會使用CRC卡或類似的東西來檢驗各種不同想法,然後才得到第一個可被接受的解決方案,然後才能開始編碼,然後才能重構。關鍵在於:重構改變了「預先設計」的角色。如果沒有重構,你就必須保證「預先設計」正確無誤,這個壓力太大了。這意味如果將來需要對原始設計做任何修改,代價都將非常高昂。因此你需要把更多時間和精力放在預先設計上,以避免日後修改。
如果你選擇重構,問題的重點就轉變了。你仍然做預先設計,但是不必一定找出正確的解決方案。此刻的你只需要得到一個足夠合理的解決方案就夠了。你很肯定地知道,在實現這個初始解決方案的時候,你對問題的理解也會逐漸加深,你可能會察覺最佳解決方案和你當初設想的有些不同。只要有重構這項武器在手,就不成問題,因為重構讓日後的修改成本不再高昂。
這種轉變導致一個重要結果:軟體設計朝向簡化前進了一大步。過去未曾運用重構時,我總是力求得到靈活的解決方案。任何一個需求都讓我提心吊膽地猜疑:在系統壽命期間,這個需求會導致怎樣的變化?由於變更設計的代價非常高昂,所以我希望建造一個足夠靈活、足夠強固的解決方案,希望它能承受我所能預見的所有需求變化。問題在於:要建造一個靈活的解決方案,所需的成本難以估算。靈活的解決方案比簡單的解決方案復雜許多,所以最終得到的軟體通常也會更難維護 — 雖然它在我預先設想的??方向上,你也必須理解如何修改設計。如果變化只出現在一兩個地方,那不算大問題。然而變化其實可能出現在系統各處。如果在所有可能的變化出現地點都建立起靈活性,整個系統的復雜度和維護難度都會大大提高。當然,如果最後發現所有這些靈活性都毫無必要,這才是最大的失敗。你知道,這其中肯定有些靈活性的確派不上用場,但你卻無法預測到底是哪些派不上用場。為了獲得自己想要的靈活性,你不得不加入比實際需要更多的靈活性。
有了重構,你就可以通過一條不同的途徑來應付變化帶來的風險。你仍舊需要思考潛在的變化,仍舊需要考慮靈活的解決方案。但是你不必再逐一實現這些解決方案,而是應該問問自己:『把一個簡單的解決方案重構成這個靈活的方案有多大難度?』如果答案是「相當容易」(大多數時候都如此),那麼你就只需實現目前的簡單方案就行了。
重構可以帶來更簡單的設計,同時又不損失靈活性,這也降低了設計過程的難度,減輕了設計壓力。一旦對重構帶來的簡單性有更多感受,你甚至可以不必再預先思考前述所謂的靈活方案 — 一旦需要它,你總有足夠的信心去重構。是的,當下只管建造可運行的最簡化系統,至於靈活而復雜的設計,唔,多數時候你都不會需要它。
勞而無獲— Ron Jeffries
Chrysler Comprehensive Compensation(克萊斯勒綜合薪資系統)的支付過程太慢了。雖然我們的開發還沒結束,這個問題卻已經開始困擾我們,因為它已經拖累了測試速度。
Kent Beck、Martin Fowler和我決定解決這個問題。等待大夥兒會合的時間里,憑著我對這個系統的全盤了解,我開始推測:到底是什麼讓系統變慢了?我想到數種可能,然後和夥伴們談了幾種可能的修改方案。最後,關於「如何讓這個系統運行更快」,我們提出了一些真正的好點子。
然後,我們拿Kent的量測工具度量了系統性能。我一開始所想的可能性竟然全都不是問題肇因。我們發現:系統把一半時間用來創建「日期」實體(instance)。更有趣的是,所有這些實體都有相同的值。
於是我們觀察日期的創建邏輯,發現有機會將它優化。日期原本是由字元串轉換而生,即使無外部輸入也是如此。之所以使用字元串轉換方式,完全是為了方便鍵盤輸入。好,也許我們可以將它優化。
於是我們觀察日期怎樣被這個程序運用。我們發現,很多日期對象都被用來產生「日期區間」實體(instance)。「日期區間」是個對象,由一個起始日期和一個結束日期組成。仔細追蹤下去,我們發現絕大多數日期區間是空的!
處理日期區間時我們遵循這樣一個規則:如果結束日期在起始日期之前,這個日期區間就該是空的。這是一條很好的規則,完全符合這個class的需要。採用此一規則後不久,我們意識到,創建一個「起始日期在結束日期之後」的日期區間,仍然不算是清晰的代碼,於是我們把這個行為提煉到一個factory method(譯註:一個著名的設計模式,見《Design Patterns》),由它專門創建「空的日期區間」。
我們做了上述修改,使代碼更加清晰,卻意外得到了一個驚喜。我們創建一個固定不變的「空日期區間」對象,並讓上述調整後的factory method每次都返回該對象,而不再每次都創建新對象。這一修改把系統速度提升了幾乎一倍,足以讓測試速度達到可接受程度。這只花了我們大約五分鍾。
我和團隊成員(Kent和Martin謝絕參加)認真推測過:我們瞭若指掌的這個程序中可能有什麼錯誤?我們甚至憑空做了些改進設計,卻沒有先對系統的真實情況進行量測。
我們完全錯了。除了一場很有趣的交談,我們什麼好事都沒做。
教訓:哪怕你完全了解系統,也請實際量測它的性能,不要臆測。臆測會讓你學到一些東西,但十有八九你是錯的。
⑩ 誰能解釋一下什麼叫資料庫
資料庫就是"按照數據結構來組織、存儲和管理數據的倉庫",在經濟管理的日常工作中,常常需要把某些相關的數據放進這樣"倉庫",並根據管理的需要進行相應的處理。例如,一些單位常常要把職工的基本情況(比如姓名、性別、年齡、工資、基本狀況等)存放在表中,這張表就可以看成是一個資料庫,通過它就可以根據需要隨時查詢某職工的基本情況,也可以查詢某個年齡段內的職工人數等等。這些工作如果都能在計算機上自動進行,那我們的人事管理就可以達到極高的水平。此外,在財務管理、倉庫管理、生產管理等管理事業中也需要建立眾多的這種"資料庫",使其可以利用計算機實現財務、倉庫、生產的自動化管理。
說白了,資料庫就像是按行列順序排列的很科學的數據集合。可以隨時按某種順序(或行或列)進行添加,想用時隨時可以按任意一種順序讀取數據,十分方便。