四、需求分析→數據庫設計
??
?? 從這開始,就真正進入項目實戰啦。先說點體會,我剛開始接觸編程的時候,都是編寫一些小東西,往往都是半天或者一天什么的就編完了,那時候根本沒想過做程序之前還要有需求分析。經過快兩年的學習,接觸的都是比較大的系統,才明白沒有需求分析的程序都太業余了,沒有任何技術含量。對于一個系統來說,如果需求分析不到位,那么將有災難性的后果,從這節的小標題就能看出,需求是數據庫設計的基石,需求定了,數據庫基本上就定了,數據庫定了,程序的基本功能也就定了。我們以一個簡單的學生管理系統為例子,來分析一下需求。分析需求地球人一般都是用UML圖,啥是UML圖呢,就是一種把程序用圖形表示的標準,它可以表示需求、程序流程、程序模塊、程序功能等等,可以說,UML圖畫完了,程序基本上就出來了,目前比較好的畫UML的工具是Rational rose,不多說啦,剩下的就交給google了。本系統的需求非常簡單,就是老師可以添加、刪除、修改學生記錄,學生的記錄包括:學號、年級、班級、姓名、性別、年齡、備注(這些就是字段)。根據這些敘述,我們可以畫出UML用例圖(用例圖就是用來分析需求的):
?
?
?? 根據需求分析我們就可以設計數據庫了,非常“簡單”嘛,需要一個表就行了,把它命名為student表,里邊添加剛剛提的那些字段就可以了。注意,數據庫中的一切,包括:數據庫名、表名、字段名、存儲過程等等,都要用英文,不可以出現中文,因為咱是專業菜鳥,不走業余路。接著往下看,教你如何創建數據庫。??
?? 作為專業教程,俺不會教你用鼠標建立數據庫,咱們要用T-SQL語句建立數據庫,也就是寫數據庫腳本。這樣建立數據庫,相當于留了個備份,無論到哪,只要有SQL環境,直接執行一下腳本數據就建好了,非常方便快捷,就算是第一次寫腳本,也比用鼠標建立數據庫快。在大型系統開發時,腳本還可以作為數據庫維護的依據,非常有用。那么怎樣寫呢,打開SQL server 2005 Management Studio,輸入帳號密碼登錄平臺,然后點一下左上角的"新建查詢"就可以打開查詢分析器了,我們可以在這輸入任何SQL語句。
?? 第一步先創建數據庫,我先把創建數據庫的標準格式給大家:
create database studentManager On primary ( name=student_data, filename='E:\SQL Server2008 SQLFULL_CHS\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\student_data.mdf', size=3, maxsize=unlimited, filegrowth=1 ) Log on (name=student_log, filename='E:\SQL Server2008 SQLFULL_CHS\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\student_log.ldf', size=1, maxsize=20,
?
?? 相信看著這個很多人都蒙了,簡單說一下,其實這么多代碼,也就第一句最重要,意思是創建一個名字叫studentManager的數據庫。On primary下邊的是對數據庫的一些初始設置,比如:路徑、初始大小、增量等等。Log on下邊的是對數據庫日志的設置,也是那么幾項。很明確的告訴大家,除非是特殊需求,否則我們沒必要管那么多,默認的就夠咱們用了,創建數據庫就一句話:create database studentManager,輸入完后點一下工具欄上的“執行”,就搞定啦。數據庫建完了,就該在數據庫里建表了,還是先給出代碼:
?
--指定數據庫 use t_studentManager; --創建t_student表 create table t_student ( number varchar(20) PRIMARY KEY, --PRIMARY KEY 是主鍵約束 grade varchar(10) NOT NULL, --NOT NULL是非空約束 class varchar(10) NOT NULL, [name] varchar(20) NOT NULL, --name屬于sql保留字,所以用方括號括起來 sex varchar(1) NOT NULL CHECK(sex in ('男','女')), --CHECK約束,意思是性別字段只能是男或女。 age int NOT NULL, remark varchar(100), addTime datetime DEFAULT(getdate())--默認值約束,getdate()獲取服務器時間 );
?? 給大家解釋一下,剛剛我們創建完數據庫,在這要引用一下,也就是use,這樣才可以在指定數據庫中建表。
??create table當然就是建表的意思了,在表名前最好加一個"t_",表示是表(table),這樣容易區分,而且專業。括號里的就是這個表中的字段,格式是:字段名類型 約束,注意每個字段寫完后邊都要加逗號(最后一個就不用加啦),表示分隔。舉這個例子,約束用的還是比較全的,重點說說約束。約束可是數據庫中相當重要的東西,它保證了數據庫的安全和穩定,同時也保證了數據完整性。約束主要有6種,分別是:NOT NULL約束(非空約束)、PRIMARY KEY約束(主鍵約束)、FOREIGN KEY約束(外鍵約束)、UNIQUE約束(唯一約束)、CHECK約束(檢查約束)、DEFAULT約束(默認值約束)。這些約束可以用在任何字段的后邊,一個字段也可以有多個約束,用空格分隔即可,比如上邊的sex字段,就同時使用了非空約束和檢查約束。當然,有些約束只能用一次,比如主鍵約束。我只是提了一下這些常用約束,大家了解我的目的就達到了,以后具體用到,再去google,就怕你不知道有這些約束。在查詢分析器中執行這段代碼,表就建立好了,提示一下:SQL查詢分析器可以選中執行,也就是你選中那些代碼就執行那些代碼,建表的時候注意不要再次執行建數據庫的語句哦。
?
?? 五、優化數據庫。
?? 數據庫設計是程序的根基,也是一門藝術。上一節我們設計的數據庫,太隨意了,什么都沒有考慮,作為專業菜鳥,這樣是不行的。
?? 優化數據庫,先要了解數據庫設計三范式,簡單說下:
?? 1.第一范式:是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重復的屬性。
?? 2.第二范式:第二范式需要確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。
?? 3.第三范式:第三范式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。
?? 這三個范式大致的意思就是:數據庫中表的職責要單一,依賴關系明確,盡量減少數據庫數據冗余。從網上查,可以查到很多個人理解,我在這也不理解了,核心思想就是我剛剛說的。我首先聲明,三范式只是一個整體的指導思想,并不可能完全遵從,有時候數據冗余未必是壞事,要考慮實際情況。
?? 很明顯,剛剛我們設計的數據庫不符合三范式的要求。在此表中學生應該依賴的是學號,而我們冒昧的把班級、年級也放在了這里,學生當然也應該依賴于班級、年級。這樣一來,表就亂了,造成的直接后果就是數據不完整,比如我們由于失誤,插入了一個年級是100的學生,而根本就沒有100這個班級。這樣還有個比較大的問題就是數據冗余,因為我們每插入一個學生,不得不記錄一次班級、年級,造成大量無用數據。所以我們要改,要把一個表拆成三個,分別是:年級表、班級表、學生表。這樣一來,數據庫就顯得漂亮多了。剛剛是一個表,我們還應付得過來,現在三個表,記不住了怎么辦?別急,剛剛提到了UML圖,它可以用來設計數據庫。在程序設計過程中,數據庫中的每一個表,都會在程序中映射成一個類,而表中的每一個字段,都是類中的一個屬性,它們的類型是一致的,我們管他叫做實體類(可以提前google一下三層架構哦),這時我們可以借助于UML中的類圖畫出數據庫的結構。如下圖:
?
?
?? 通過UML類圖,清晰的描述了表之間的關系。所以,在大型項目開發中,必須借助工具設計數據庫,展示數據庫的結構和關系,這樣我們才能優化、改進數據庫,數據庫不是一下就能設計成功的,往往要根據需求的理解而發生變動。很多童鞋可能會問為什么用實體類,我只說一句話:用實體類便于在程序中對數據庫進行操作,實體類是對數據的打包,便于數據傳遞。剩下的就要去google啦~不多說。這下我們的數據庫設計算是完工了,刪掉原來的數據庫,對照這UML實體類圖寫優化后的數據庫腳本,代碼如下:
?
--創建數據庫 create database studentManager; --指定數據庫 use t_studentManager; --創建年級表 create table t_grade ( id bigint IDENTITY(1,1) PRIMARY KEY, [name] varchar(10) NOT NULL ); --創建班級表 create table t_class ( id bigint IDENTITY(1,1) PRIMARY KEY, gradeID bigint NOT NULL, [name] varchar(10) NOT NULL, CONSTRAINT FK_class_gradeID FOREIGN KEY(gradeID) REFERENCES t_grade(id) --外鍵約束 ); --創建t_student表 create table t_student ( number varchar(20) PRIMARY KEY, --PRIMARY KEY 是主鍵約束 classID bigint NOT NULL, [name] varchar(20) NOT NULL, --name屬于sql保留字,所以用方括號括起來 sex varchar(1) NOT NULL CHECK(sex in ('男','女')), --CHECK約束,意思是性別字段只能是男或女。 age int NOT NULL, remark varchar(100), addTime datetime DEFAULT(getdate()),--默認值約束,getdate()獲取服務器時間 CONSTRAINT FK_student_classID FOREIGN KEY(classID) REFERENCES t_class(id) --外鍵約束 );
?? 在講代碼之前,必須先說什么是外鍵約束,外鍵約束就是:A表的某個字段用到了B表的主鍵字段,那么A表中的這個字段就叫外鍵,A、B兩個表間的約束關系就叫外鍵約束。A表的外鍵字段必須依賴于B表的主鍵字段,如果向A表外鍵字段中添加一個B表主鍵字段中不存在的數據,那么將失敗。外鍵約束保證了數據的完整性和合理性。
?? 這段代碼,我還是要重點說說約束,與上一次創建表不同的是,不僅僅是表多了,而且最后多了外鍵約束,CONSTRAINT是創建一個約束,后邊接約束名;FOREIGN KEY代表該約束是外鍵約束,括號里寫字段名,代表這個字段是外鍵;REFERENCES是參考的意思,也就是參考哪個表里的哪個字段,也就是主鍵在哪,后邊接"表名(字段名)"。其實我是故意把它寫在最后的邊的,外鍵約束也是約束,完全可以放在字段定義的最后邊,也就是NOT NULL那個位置上,我這樣寫是想告訴大家還有另一種寫法,所有的約束都可以類似這樣寫,就是換個位置,我現在提出來避免大家以后見到發蒙。需要注意的是,創建表的括號里,無論是寫約束還是寫字段,都要用逗號分隔,千萬別忘了。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
