在數(shù)據(jù)庫中使用對(duì)象的好處_第1頁
在數(shù)據(jù)庫中使用對(duì)象的好處_第2頁
在數(shù)據(jù)庫中使用對(duì)象的好處_第3頁
在數(shù)據(jù)庫中使用對(duì)象的好處_第4頁
在數(shù)據(jù)庫中使用對(duì)象的好處_第5頁
已閱讀5頁,還剩24頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

在數(shù)據(jù)庫中使用對(duì)象的好處我們都知道如何從Mysql獲取我們需要的行(記錄),讀取數(shù)據(jù),然后存取一些改動(dòng)。彳艮明顯也很直接,在這個(gè)過程背后也沒有什么拐彎抹角的。然而對(duì)于我們使用面對(duì)對(duì)象的程序設(shè)計(jì)(OOP)來管理我們數(shù)據(jù)庫中的數(shù)據(jù)時(shí),這個(gè)過程就需要大大改進(jìn)一下了。這篇文章將對(duì)如何設(shè)計(jì)一個(gè)面對(duì)對(duì)象的方式來管理數(shù)據(jù)庫的記錄做一個(gè)簡單的描述。你的數(shù)據(jù)當(dāng)中的所有內(nèi)部邏輯關(guān)系將被封裝到一個(gè)非常條理的記錄對(duì)象,這個(gè)對(duì)象能夠提供專門(專一)的確認(rèn)代碼系統(tǒng),轉(zhuǎn)化以及數(shù)據(jù)處理。隨著ZendEngine2和PHP5的發(fā)布,PHP開發(fā)者將會(huì)擁有更強(qiáng)大的面對(duì)對(duì)象的工具來輔助工作,這將使這個(gè)過程(面對(duì)對(duì)象地管理數(shù)據(jù)庫)更有吸引力。以下列出了一些使用對(duì)象來描敘你的數(shù)據(jù)庫的有利方面:1、存取方法(Accessormethods)將會(huì)使你對(duì)屬性的讀取和寫入過程做到完全的控制2、每一級(jí)的每個(gè)記錄和屬性(的操作)都有確認(rèn)過程3、從關(guān)系表中智能的獲取對(duì)象4、重復(fù)使用的邏輯方法意味著所有的數(shù)據(jù)交互都要通過相同的基礎(chǔ)代碼(codebase),這將使維護(hù)變得更加簡單5、代碼簡單,因?yàn)椴煌挠涗浀膬?nèi)部邏輯都已經(jīng)包含在各自所處的類(class)當(dāng)中,而不是繁瑣的庫(lib)文件6、在手工編寫代碼和SQL查詢語句時(shí),出錯(cuò)的機(jī)會(huì)將更少存取方法(Accessormethods)存取方式是通過類給實(shí)例(instance)的變量賦值。一個(gè)例子,我有一個(gè)叫User的類,并且有一個(gè)實(shí)例$username,我會(huì)寫這樣的存取方法(函數(shù)),User->username()和User->setUsername()用來返回和給實(shí)例賦值。<?phpclassUser(var$username;functionusername()(return$this->username;}functionsetUsername($newUsername)($this->username=$newUsername;}}?>這里有很好的理由讓我們編寫這樣的“特別的代碼”。它將使開發(fā)者更靈活的改變類的繁瑣的工作,因?yàn)檫@一過程將不需要其他的使用類的php代碼。讓我們來看看下面這個(gè)更加完善的可信賴的User類。變量$username將不復(fù)存在,所有的東西都被整合的放在數(shù)組$_data當(dāng)中如果username是空的話,username()函數(shù)將提供一個(gè)缺省(默認(rèn))的值給它setUsername()過程將在接受值之前確認(rèn)username是否合乎標(biāo)準(zhǔn)格式(如字長等)<?phpclassUser(var$_data=array();//associativearraycontainingalltheattributesfortheUserfunctionusername()(return!empty($this->_data[\'username\'])?$this->_data[\'username\']:\'(noname!)\';}functionsetUsername($newUsername)(if($this->validateUsername($newUsername))($this->_data[\'username\']=$newUsername;}}functionvalidateUsername(&$someName)(if(strlen($someName)>12)(thrownewException(\,Yourusernameistoolong\高性能的數(shù)據(jù)庫第一講:范式設(shè)計(jì)首先,俺說,數(shù)據(jù)庫重在設(shè)計(jì),然后才是開發(fā)。按照第三范式開發(fā),會(huì)讓你提升到一個(gè)新的境界!名詞解釋:第三范式第一范式:一個(gè)不包含重復(fù)列的表歸于第一范式。第二范式:如果一個(gè)表歸于第一范式且只包含依賴于主鍵的列,則歸于第二范式。第三范式:如果一個(gè)表歸于第二范式且只包含那些非傳遞性地依賴于主鍵的列,則歸于第三范式。chair3口述簡單解釋:第一范式:不設(shè)計(jì)重復(fù)字段的表比如:CreateTabletb1(fd1varchar(20),--用來存放電話fd2varchar(20),--用來存放電話fd3int--其他)則fd1,fd2違反第一范式第二范式:第二范式:不設(shè)計(jì)沒有主鍵,或沒有唯一索引的表比如:如果一個(gè)表存在相同的數(shù)據(jù),那必然是違反第二范式無疑。第三范式:能細(xì)分則細(xì)分每個(gè)字段。比如:一個(gè)表,原來設(shè)計(jì)為:CreateTAbleClothes(ClothesIDintprimarykey,--IDColorvarchar(10),--顏色Descriptionvarchar(20)--描述)那么Color違反了第三范式于是,第三范式應(yīng)該這樣設(shè)計(jì)CreateTAbleClothes(ClothesIDintprimarykey,--IDColorlDInt,--顏色I(xiàn)DDescriptionvarchar(20)--描述)CreateTableColor(ColorIDintprimarykey,Colorvarchar(20))Color作為主表,Clothes作為子表,兩者用ColorID互聯(lián).三范式設(shè)計(jì)的好處:減少數(shù)據(jù)冗余,提高系統(tǒng)可維護(hù)性,提高系統(tǒng)可擴(kuò)展性。三范式設(shè)計(jì)的缺點(diǎn):會(huì)降低數(shù)據(jù)庫的性能。(嘻嘻,不過非常少,大家放心)第二講數(shù)據(jù)庫編程編程準(zhǔn)則:(簡單說說)數(shù)據(jù)邏輯的放在一塊業(yè)務(wù)邏輯的放在一塊作界面的只做界面最小網(wǎng)絡(luò)傳輸1、數(shù)據(jù)邏輯的放在一塊比如,表:History那么,存儲(chǔ)過程:spWriteHistory表示數(shù)據(jù)邏輯:就是對(duì)History的寫操作同樣,存儲(chǔ)spQueryHistoryFromHistorylD表示根據(jù)HistorylD對(duì)History記錄的查詢?cè)偻瑯?,spQueryHistoryFromHistoryID;2(;不是普通的分號(hào),是存儲(chǔ)過程組)表示HistorylD對(duì)History記錄查詢的另外一個(gè)類似的方法2、業(yè)務(wù)邏輯比如,還書,則spReturnBook購買,則spBuyBook此時(shí)可能要調(diào)用很多表,或很多數(shù)據(jù)邏輯:如CreateProcspBuyBook(@iBookIDint,--書ID@iOperatorIDint--操作員ID)--Name:spBuyBook--Func:購買一本書--Var:見上--Use:spWriteOperateRecord,spProc2,spProc3....--User:Chair3,Chair4--Author:Chair3#SapphireStudio()--Date:2003-4-16--Memo:臨時(shí)寫寫的,給大家作個(gè)SampleASBeginBeginTran--數(shù)據(jù)邏輯:更新Book表,減少數(shù)量UpdateBookSetBookNumber=BookNumber-1WhereBookID=@iBookID...--業(yè)務(wù)邏輯:寫入操作記錄ExecspWriteOperateRecord'某某人出售了一本書,書的ID為XXX,CommitTranEnd不要試圖一個(gè)存儲(chǔ)過程做完所有的事情,應(yīng)當(dāng)考慮將部分代碼分為更小的存儲(chǔ)過程,以達(dá)到代碼公用以及可維護(hù)性。當(dāng)然,要求性能很高的部分,最好還是單獨(dú)完成。3、界面的程序不要直接調(diào)用數(shù)據(jù)表。俺在賽格的時(shí)候,不允許其他同事直接讀取表的,他們只能有調(diào)用StoreProcedure的權(quán)限.這個(gè)根據(jù)開發(fā)環(huán)境而定,當(dāng)然不是絕對(duì),盡量如此.這樣,可以降低因?yàn)樾薷臄?shù)據(jù)表而要對(duì)所有程序修改,檢查的后果。4、最小網(wǎng)絡(luò)傳輸4.1減少使用Select*....語句,選擇你只需要的數(shù)據(jù),SelectFd1,fd2Fromtb14.2減少客戶端對(duì)數(shù)據(jù)庫表的直接操作(與3有點(diǎn)同)4.2避免在客戶端對(duì)數(shù)據(jù)庫的循環(huán)寫操作,把循環(huán)轉(zhuǎn)移到服務(wù)器來.4.3......忘了...靠經(jīng)驗(yàn)了4點(diǎn)最為重要,許多人的程序速度很慢,都是由于網(wǎng)絡(luò)傳輸過多的緣故。最后小結(jié):優(yōu)秀的程序員更重于對(duì)整體上的設(shè)計(jì)、可維護(hù)性、可擴(kuò)展性的設(shè)計(jì)。第三講設(shè)計(jì)細(xì)節(jié)到現(xiàn)在已經(jīng)是第三講了,也不知道聽眾幾何......說得好的話,送之鮮花,說得不好的話,丟個(gè)雞蛋把!好歹也讓我chair3知道有幾個(gè)人聽了。好,廢話少說,nowbegin:要點(diǎn)1.約束2.默認(rèn)值3.計(jì)算字段4.索引以上乃數(shù)據(jù)庫設(shè)計(jì)以及編程的最常用的部分了,下面聽我一一將來1、約束。約束?何為約束?也就是對(duì)某一字段數(shù)值限定。以維護(hù)數(shù)據(jù)庫數(shù)據(jù)的最黨的純潔性。一流的程序員打一開始,就應(yīng)當(dāng)知道某一字段的填寫范圍。算了,理論不說了,舉例子:CreateTablePeople(Namevarchar(20)NotNull,--姓名AgeintNotNullCheck(Age>0)--年齡)大伙看了AgeintNotNullCheck(Age>0),中的Check(Age>0)就是防止用戶不小心填寫入<0的數(shù)值。哈哈,難道娘胎里的就算是一1歲么?顯然國務(wù)院沒有如此規(guī)定。因此必須強(qiáng)迫Age>0。2、默認(rèn)值。什么叫默認(rèn)值不用我說了。數(shù)據(jù)表設(shè)計(jì)中,盡量避免Null的字段。采用默認(rèn)值。還是舉例子有說服力!看:CreateTablePeople(Namevarchar(20)NotNull,--姓名SexbitNotNullDefault1,--性別AgeintNotNullCheck(Age>0)--年齡)看到了沒?SexbitNotNullDefault1,性別,也就“男”或者“女”,用數(shù)字表示也就1or0。在防止數(shù)據(jù)字段出現(xiàn)更多的情況(比如null),就必須使用notnull。照顧很多懶蟲一般的客戶(好像是說自己了),就給他默認(rèn)一個(gè)“男”好了!唉,畢竟男女不打平等,很多地方都是男得多。(痛苦中…)這里僅僅是舉個(gè)例子,很多地方都可以用得到,比如日期之類的。請(qǐng)盡量避免null,而采用notnull+default能夠更為純潔你的數(shù)據(jù)庫。3、計(jì)算字段優(yōu)秀的設(shè)計(jì)人員,一開始就應(yīng)當(dāng)知道如何考慮到以后的使用的問題。比如在一個(gè)學(xué)生的表中(我這里是舉個(gè)例子,實(shí)際上我不會(huì)寫死subject的數(shù)量的)CreateTableStudent(StudentIDintprimarykey,ChineseFloatnotnulldefault0,EnglishFloatnotnulldefault0,MathematicsFloatnotnulldefault0SumAsChinese+English+Mathematics,AverageAs(Chinese+English+Mathematics)/3,????)相信這里聰明的人甚多,這個(gè)說些什么好呢?肚子有點(diǎn)餓......堅(jiān)持一下,寫完第4點(diǎn)馬上作飯吃!4、索引這可是這里設(shè)計(jì)中的最最最最最最最最最最最最最最最最最最最最重要的部分?。?shù)據(jù)庫的性能取決于索引的設(shè)計(jì)的好壞。俺先給大家大致講講索引的種類:聚類索引,非聚類索引(ClusteredIndexandnonClusteredindex)聚類索引通常創(chuàng)建于主鍵,主要?jiǎng)?chuàng)建于這些字段1、主鍵、外建2、返回某范圍的數(shù)據(jù)非聚類索引通常用于1、亂糟糟的數(shù)據(jù),很多都不一樣D2、而且數(shù)據(jù)經(jīng)常要更改D這樣說大家似乎都不是很明白吧?來吧,來吧,相約DevClu吧!CreateTableOperateRecord(--操作記錄OperateRecordIDintprimarykey,--流水號(hào)OperatorlDintnotnull,--操作員IDOperationvarchar(100),--操作內(nèi)容OperateDateDAteTime,--時(shí)間Memovarchar(30)--備注)比如,在這里,如果經(jīng)常要求對(duì)該操作員進(jìn)行查詢,那么OperatorlD就應(yīng)該采用聚類索引,如果還經(jīng)常對(duì)操作內(nèi)容進(jìn)行查詢,那么Operation就應(yīng)該采用非聚類索引。于是:CreateUNIQUECLUSTEREDIndexidxOperateRecord_OperateREcordIDOnOperateRecord(OperateREcordID)GoCreateIndexidxOperateRecord_OperationOnOperateRecord(Operation)Go使用索引:Select*FromOperateRecordWith(Index=(idxOperateRecord_OperateREcordID))--指定索引查詢WhereOperateRecordIDbetween1and20000--條件是OperateRecordID.orderbyOperateRecordID大家看明白了否?我肚子很餓了,沒力氣說了:(:(試驗(yàn)證明,優(yōu)秀的索引將大大提高查詢的速度.chair3以前曾經(jīng)作個(gè)一個(gè)例子:pIII(好像是500),128MRam,Win2KServer,SQLServerEnterpriseHistory表為1000萬的數(shù)據(jù)。1、使用聚類索引,我提取100萬,耗時(shí)1分鐘;提取1條,耗時(shí)2秒(我可能記錯(cuò)了,可能不用2秒的...我現(xiàn)在的機(jī)器都是一瞬間就提取出來了,不過我現(xiàn)在用P4,512內(nèi)存。數(shù)據(jù)為1800萬)2、不使用任何索引(我把索引刪掉),提取1條記錄,耗時(shí)55秒;提取100萬數(shù)據(jù)我不敢,我怕死機(jī)。當(dāng)然也不是索引越多越好,索引越多,將會(huì)影響寫的速度。一般說,一個(gè)表,有2-3個(gè)索引即可。根據(jù)實(shí)際情況第四講編程細(xì)節(jié)觸發(fā)器游標(biāo)函數(shù)存儲(chǔ)過程事務(wù)1、觸發(fā)器。定義:何為觸發(fā)器?在SQLServer里面也就是對(duì)某一個(gè)表的一定的操作,觸發(fā)某種條件,從而執(zhí)行的一段程序。觸發(fā)器是一個(gè)特殊的存儲(chǔ)過程。常見的觸發(fā)器有三種:分別應(yīng)用于Insert,Update,Delete事件。(SQLServer2000定義了新的觸發(fā)器,這里不提)我為什么要使用觸發(fā)器?比如,這么兩個(gè)表:CreateTableStudent(--學(xué)生表StudentIDintprimarykey,--學(xué)號(hào)????)CreateTableBorrowRecord(--學(xué)生借書記錄表BorrowRecordintidentity(1,1),--流水號(hào)StudentIDint,--學(xué)號(hào)BorrowDatedatetime,--借出時(shí)間ReturnDAteDatetime,--歸還時(shí)間)用到的功能有:如果我更改了學(xué)生的學(xué)號(hào),我希望他的借書記錄仍然與這個(gè)學(xué)生相關(guān)(也就是同時(shí)更改借書記錄表的學(xué)號(hào));如果該學(xué)生已經(jīng)畢業(yè),我希望刪除他的學(xué)號(hào)的同時(shí),也刪除它的借書記錄。等等。這時(shí)候可以用到觸發(fā)器。對(duì)于1,創(chuàng)建一個(gè)Update觸發(fā)器:CreateTriggertruStudentOnStudentforUpdate--Name:truStudent--func:更新BorrowRecord的StudentID,與Student同步。--Use:None--User:System--Memo:臨時(shí)寫寫的,給大家作個(gè)Sample。沒有調(diào)試阿。AsifUpdate(StudentID)beginUpdateBorrowRecordSetbr.StudentID=i.StudentIDFromBorrowRecordbr,Deletedd,InsertediWherebr.StudentID=d.StudentIDend理解觸發(fā)器里面的兩個(gè)臨時(shí)的表:Deleted,Inserted。注意Deleted與Inserted分別表示觸發(fā)事件的表“舊的一條記錄”和“新的一條記錄”。一個(gè)Update的過程可以看作為:生成新的記錄到Inserted表,復(fù)制舊的記錄到Deleted表,然后刪除Student記錄并寫入新紀(jì)錄。對(duì)于2,創(chuàng)建一個(gè)Delete觸發(fā)器CreatetriggertrdStudentOnStudentforDelete--Name:trdStudent--func:同時(shí)刪除BorrowRecord的數(shù)據(jù)--Use:None--User:System--Memo:臨時(shí)寫寫的,給大家作個(gè)Sample。沒有調(diào)試阿。AsDeleteBorrowRecordFromBorrowRecordbr,DelteddWherebr.StudentID=d.StudentID從這兩個(gè)例子我們可以看到了觸發(fā)器的關(guān)鍵:A.2個(gè)臨時(shí)的表;B.觸發(fā)機(jī)制。這里我們只講解最簡單的觸發(fā)器。復(fù)雜的容后說明。事實(shí)上,我不鼓勵(lì)使用觸發(fā)器。觸發(fā)器的初始設(shè)計(jì)思想,已經(jīng)被“級(jí)聯(lián)”所替代。2.游標(biāo)在SQL2000之前,游標(biāo)可謂是SQLServer心中的痛:老牛般的速度(CPU),河馬般的胃口(內(nèi)存)??赡銋s不能不用他。什么叫游標(biāo)呢?說白了就是像高級(jí)語言一樣,是存放數(shù)據(jù)集,并逐條訪問的一種機(jī)制。比如在Delphi里面,要實(shí)現(xiàn)類似于這樣的功能:(呵呵,不好意思,我只會(huì)Delphi,所以只能舉一個(gè)Delphi的例子)//這是一段Delphi的源代碼adoDataSet1.Close;adoDataSet1.CommandText:='Select*FromStudentorderbyStudentID';adoDataSet1.Open;WhileNotadoDAtaSet1.EofDoBeginYourVar:=adoDAtaSet1.FieldByName('StudentID').AsInteger;DoSomeThing();adoDataSet1.Next;End在SQLServer并沒有很好的數(shù)據(jù)逐條訪問機(jī)制,如果有,那就是游標(biāo)。還是舉例子:對(duì)于表CreateTableBorrowRecord(--學(xué)生借書記錄表BorrowRecordintidentity(1,1),--流水號(hào)StudentIDint,--學(xué)號(hào)StudentFeeIDint,--費(fèi)用結(jié)算號(hào)(外鍵)BorrowDatedatetime,--借出時(shí)間ReturnDAteDatetime,--歸還時(shí)間FeeMoney--借書費(fèi)用???)CreateTableStudentFee(--學(xué)生費(fèi)用結(jié)算表StudentFeelDintprimarykey,--費(fèi)用結(jié)算號(hào)(主鍵)StudentIDint,--學(xué)號(hào)BorrowBookAllFeeMoney,--所有借書總費(fèi)用???)兩者關(guān)系為多對(duì)一的關(guān)系,關(guān)聯(lián)字段為StudentFeelD由于某種原因StudentFee表的數(shù)據(jù)遭到了破壞,我想StudentFee循環(huán)一遍將“所有借書總費(fèi)用”重算。--Name:一部分代碼--func:更新學(xué)生借書總費(fèi)用--Use:--User:--Memo:臨時(shí)寫寫的,給大家作個(gè)Sample。沒有調(diào)試阿。--聲明一個(gè)游標(biāo)DeclarecurStudentFeeCursorforSelectStudentFeeIDFromStudentFee--聲明兩個(gè)費(fèi)用變量Declare@mBorrowBookAllFeeMoney--總費(fèi)用Declare@iStudentFeeIDInt--借書結(jié)算號(hào)--初始化Set@mBorrowBookAllFee=0Set@iStudentFeeID=0--打開游標(biāo)OpencurStudentFee--循環(huán)并提取記錄FetchNextFromcurStudentFeeInto@iStudentFeeIDWhile(@@Fetch_Status=0)begin--從借書記錄中計(jì)算某一學(xué)生的借書總記錄的總費(fèi)用Select@mBorrowBookAllFee=Sum(BorrowBookAllFee)FromBorrowRecordWhereStudentFeeID=@iStudentFeeID--更新到匯總表。UpdateStudentFeeSetBorrowBookAllFee=@mBorrowBookAllFeeWhereStudentFeeID=@iStudnetFeeIDFetchNextFromcurStudentFeeInto@mFeeend--關(guān)閉游標(biāo)ClosecurStudentFee--釋放游標(biāo)DeallocatecurStudentFee關(guān)注游標(biāo)的要點(diǎn):1、聲明、打開、關(guān)閉、釋放;2、@@Fetch_Status游標(biāo)提取狀態(tài)標(biāo)志,0表示正確這里,我也要提到,我不鼓勵(lì)使用游標(biāo)。更多的情況下,在SQL2000里面,函數(shù)已經(jīng)能夠?qū)崿F(xiàn)絕大部分游標(biāo)的功能。3、函數(shù)。函數(shù)是SQL2000的新功能。一般的編程語言都有函數(shù),我就不用解釋函數(shù)是什么東東了。:)或許不少朋友會(huì)問:我用存儲(chǔ)過程不就可以了么,我為什么要使用函數(shù)?這里特別指出的一點(diǎn):fn可以嵌套在Select語句中使用,而sp不可以。這里不打算大批特批一番游標(biāo)了,當(dāng)然,在我的程序里面,基本拋棄了游標(biāo)(這里特別說明,是“基本”!因?yàn)檫€是有很多地方費(fèi)用導(dǎo)游表不可的。),轉(zhuǎn)而采用了fn。游標(biāo)太消耗資源了。受不了......我快要感動(dòng)得要流淚了…fn其實(shí)要比sp要簡單得多。因?yàn)樗牟淮_定性,從而也使他受到了不少的限制。舉個(gè)函數(shù)的小粒子:CreateFunctionfnTest(@iint)ReturnsbitAsbeginDeclare@bbitif(Cast(@iAsFloat)/2)=(@i/2)Set@b=1elseSet@b=0Return@bendUsetheSample:CreateTable#TT(fd1int)Declare@iintSet@i=0While@i<=20beginInsertInto#ttvalues(@i)Set@i=@i+1endSelectfd1,'是否雙數(shù)'=dbo.fnTest(fd1)--在這里調(diào)用了函數(shù),注意哈:函數(shù)之前一定要加上他的owner.From#ttDropTable#tt有了sp的編程基礎(chǔ),寫fn也就不是什么很難的事情了。剛才我提到了,fn受到限制頗多,這里稍稍列舉:chair1.只能調(diào)用確定性函數(shù),不可以調(diào)用不確定函數(shù)。比如,不可以調(diào)用GetDate(),以及自己定義的不確定性函數(shù)。chair2.不可以使用動(dòng)態(tài)SQL。如:Execute,sp_ExecuteSQL(這是我最痛苦的事情了,痛哭中......)chair3.不可以調(diào)用擴(kuò)展存儲(chǔ)過程chair4.不可以調(diào)用Update語句對(duì)表進(jìn)行更新chair5.不可以在函數(shù)內(nèi)部創(chuàng)建表(CreateTAble),修改表(AlterTAble)4、存儲(chǔ)過程。存儲(chǔ)過程是數(shù)據(jù)庫編程里面最重要的表現(xiàn)方式了。呵呵,這里我要提到上次說道的:我拒絕使用觸發(fā)器。這里我要開始猛批一頓觸發(fā)器了。在SQL2000里,說實(shí)話,我實(shí)在找不出觸發(fā)器可以存在的理由?;貞浺幌拢河|發(fā)器是一種特殊的存儲(chǔ)過程。它在一定的事件(Insert,Update,Delete等)里自動(dòng)執(zhí)行。我建議使用sp和級(jí)聯(lián)來代替觸發(fā)器。在SQL7里面,觸發(fā)器通常用于更新、或刪除相關(guān)表的數(shù)據(jù),以維護(hù)數(shù)據(jù)的完整。SQL7里面,沒有級(jí)聯(lián)刪除和級(jí)聯(lián)修改的功能。只能建立起關(guān)系。既然SQL2000里面提供了級(jí)聯(lián),那么觸發(fā)器就沒有很好的存在理由。更多的情況下是作為一個(gè)向下兼容的技術(shù)而存在。當(dāng)然,也有人喜歡把觸發(fā)器作為處理數(shù)據(jù)邏輯,甚至是業(yè)務(wù)邏輯的自動(dòng)存儲(chǔ)過程。這種方法并不足取。這里列舉以下使用觸發(fā)器的一些壞處:a、“地下”運(yùn)行。觸發(fā)器沒有很好的調(diào)試、管理環(huán)境。調(diào)試一段觸發(fā)器,要比調(diào)試一段sp更耗費(fèi)時(shí)間與精力。b、類似于goto語句。(過分自由的另外一個(gè)說法是:無政府主義!)一個(gè)表,可以寫入多個(gè)觸發(fā)器,包括同樣forUpdate的10個(gè)觸發(fā)器!同樣forDelete的10個(gè)觸發(fā)器。也就是說,你每次要對(duì)這個(gè)表進(jìn)行寫操作的時(shí)候,你要一個(gè)一個(gè)檢查你的觸發(fā)器,看看他們是做什么的,有沒有沖突?;蛟S,你會(huì)很牛B的對(duì)我說:我不會(huì)做那么傻B的事情,我記得住我做了些什么!3個(gè)月以后呢?10個(gè)月以后呢?你還會(huì)對(duì)我說你記得住么?c、嵌套觸發(fā)器、遞歸觸發(fā)器你敢說你這么多的觸發(fā)器中不會(huì)存在Table1更新了Table2表,從而觸發(fā)Table2表更新TAble3,TAble3的觸發(fā)器再次觸發(fā)Table1更新Table2......??或許還會(huì)發(fā)生這種情況:你的程序更新了Table1.Fd1,觸發(fā)器立馬更新Table1.fd1,再次觸發(fā)事件,觸發(fā)器再次更新Tablel.fdl......當(dāng)然,SQLServer可以設(shè)置和避免應(yīng)用程序進(jìn)入死循環(huán),可是,得到的結(jié)果,或許就不是你想要的。我想不出觸發(fā)器更多的壞處了,因?yàn)槲以缇蛼仐壛怂?。算了,不批它了,酸是各人愛好把!我建議使用完全存儲(chǔ)過程來實(shí)現(xiàn)數(shù)據(jù)邏輯和事務(wù)邏輯!先講講sp的編寫格式(我個(gè)人的編程習(xí)慣)。良好的習(xí)慣有助于日后的維護(hù)。CreateProcspBuyBook(--@@存儲(chǔ)過程頭,包括名字、參數(shù)、說明文檔@iBookIDint,--書的ID--@@參數(shù)@iOperatorIDint--操作員ID)@@說明文檔--Name:spBuyBook@@名字--func:購買一本書的業(yè)務(wù)邏輯@@存儲(chǔ)過程的功能--Return:0,正確;-1,沒找到該書;-2,更新Book表出錯(cuò);-3.....@@返回值解釋--Use:spDoSomething,spDoSomething2....@@引用了那些外部程序,比如sp,fn,vw等As--@@程序開始beginBeginTran--@@激活事務(wù)ExecspDoSomething--@@調(diào)用其他spif@@Error<>0--@@判斷是否錯(cuò)誤beginRollbackTran--@@回滾事務(wù)RaisError('SQLSERVER,spBuyBook:調(diào)用spDoSomeThing發(fā)生錯(cuò)誤。',16,1)withLog--@@記錄日志Return-1--@@返回錯(cuò)誤號(hào)end....--更多其他代碼CommitTran--@@提交事務(wù)end媽的我怎么這么背啊我??什么時(shí)候不死機(jī),偏偏在這時(shí)??!丟了不少......:(:(下面默哀3分鐘..................好了,繼續(xù)!回憶剛才寫的內(nèi)容ing......AA、存儲(chǔ)過程的幾個(gè)要素:a.參數(shù)b.變量c.語句d.返回值e.管理存儲(chǔ)過程BB、更高級(jí)的編程要素:a.系統(tǒng)存儲(chǔ)過程b.系統(tǒng)表c.異常處理d.臨時(shí)表e.動(dòng)態(tài)SQLf.擴(kuò)展存儲(chǔ)過程g.DBCC命令A(yù)A.a參數(shù):知識(shí)要點(diǎn)包括:輸入?yún)?shù),輸出參數(shù),參數(shù)默認(rèn)值Sample:CreateProcspTest(@iint=0,--輸入?yún)?shù)@ointoutput--輸出參數(shù))AsSet@o=@i*2--對(duì)輸出參數(shù)付值UsetheSample:Declare@ointExecspTest33,@ooutputSelect@o--此時(shí)@o應(yīng)該等于33*2=66。AA.b變量:AA.a中已經(jīng)有聲明變量的例子了,就是Declare@ointAA.c語句:在SqlServer中,如果僅僅使用標(biāo)準(zhǔn)SQL語句將是不可想象的,通常認(rèn)為,標(biāo)準(zhǔn)的SQL語句就那么幾條,如:Select,Update,Delete因此,我們需要引入更多更強(qiáng)大的功能,那就是T-SQL語句:賦值語句:Set循環(huán)語句:While分支語句:if,Case(Case語句不能單獨(dú)使用,與一般高級(jí)語言的不同)一起舉個(gè)例子吧:Sample:Declare@iintSet@i=0While@i<100beginif@i<=20beginSelectCaseCast(@iAsFloat)/2When(@i/2)thenCast(@iAsvarchar(3))+'是雙數(shù),elseCast(@iAsvarchar(3))+'是單數(shù),endendSet@i=@i+1endAA.d返回值Sample:CreateProcspTest2AsReturn22UsetheSampleDeclare@iintExec@i=spTest2Select@iAA.e管理存儲(chǔ)過程:創(chuàng)建,修改,刪除。分別為:CreateProc...,AlterProc...,DropProc...BB、更高級(jí)的編程要素:a.系統(tǒng)存儲(chǔ)過程b.系統(tǒng)表c.異常處理d.臨時(shí)表e.動(dòng)態(tài)SQLf.擴(kuò)展存儲(chǔ)過程g.DBCC命令哈哈,以下課程收費(fèi)??!(玩笑,實(shí)際上打算放到后面去講了。)5.事務(wù)什么叫事務(wù)?這些就是數(shù)據(jù)庫特有的術(shù)語了。懶蟲在這里口頭解釋:就是把多件事情當(dāng)做一件事情來處理。也就是大家同在一條船上,要活一起活,要over一起over!我為什么要使用事務(wù)?俺這里再舉個(gè)很俗很俗的例子:俺到銀行存錢,于是有這么幾個(gè)步驟:1、把錢交給工作人員;2、工作人員填單;3、將單子給我簽字;4、工作人員確認(rèn)并輸入電腦。要是,要是我把錢交給工作人員之后,進(jìn)行到3我簽字了。那哥們突然心臟病發(fā)作,over掉了,那,我的錢還沒有輸入電腦,但我卻交了錢又簽字確認(rèn)了,而并沒有其他任何記錄。我豈不是要虧死了???我的血汗錢?。≮s緊退給我?。∮谑?,在數(shù)據(jù)庫里產(chǎn)生了這么一個(gè)術(shù)語:事務(wù)(Transaction),也就是要么成功,要么失敗,并恢復(fù)原狀。還是寫程序把:CreateProcsp我去存款(@MMoney,@iOperatorInt)AsBeginDeclare@iintBeginTran--激活事務(wù)Exec@i=sp交錢@m,@iOperatorif@i<>0--這里一般用系統(tǒng)錯(cuò)誤號(hào)@@Error。我這里為了舉例子沒有用到。需要根據(jù)實(shí)際情況。beginRollbackTran--回滾事務(wù)RaisError('銀行的窗口太少了,我懶得排隊(duì),不交了?。?',16,1)withLog--記錄日志Return-1--返回錯(cuò)誤號(hào)endExec@i=sp填單@m,@iOperatorif@i<>0beginRollbackTran--回滾事務(wù)RaisError('銀行的哥們打印機(jī)出了點(diǎn)毛病,打印不出單子來,把錢退回來給我吧??',16,1)withLogReturn-2endExec@i=sp簽字@mif@i<>0beginRollbackTran--回滾事務(wù)RaisError('我靠?什么爛銀行,換了3支筆都寫不出水來!!老子不存了??!不簽!’,16,1)withLogReturn-3endExec@i=sp輸入電腦@m,@iOperatorif@i<>0beginRollbackTran--回滾事務(wù)RaisError('什么意思?磁盤空間已滿?好了好了,把錢給我,我到旁邊的這家銀行!',16,1)withLogReturn-4endCommitTran--提交事務(wù)Return0End事務(wù)的幾個(gè)要點(diǎn)BeginTran,@@Error(我這里沒有用到,見上面的注釋),RollbackTran,CommitTran。另:事務(wù)可以嵌套使用。這個(gè)時(shí)候需要命名。請(qǐng)參見sqlserveronlinehelp。為數(shù)據(jù)庫建立索引就象許多的PHP開發(fā)者一樣,在剛開始建立動(dòng)態(tài)網(wǎng)站的時(shí)候,我都是使用相對(duì)簡單的數(shù)據(jù)結(jié)構(gòu)。PHP在連接數(shù)據(jù)庫方面的確實(shí)是十分方便(譯者注:有些人認(rèn)為PHP在連接不同數(shù)據(jù)庫時(shí)沒有一個(gè)統(tǒng)一的接口,不太方便,其實(shí)這可以通過一些擴(kuò)展庫來做到這一點(diǎn)),你無需看大量的設(shè)計(jì)文檔就可以建立和使用數(shù)據(jù)庫,這也是PHP獲得成功的主要原因之一。前些時(shí)候,一位頗高級(jí)的程序員居然問我什么叫做索引,令我感到十分的驚奇,我想這絕不會(huì)是滄海一粟,因?yàn)橛谐汕先f的開發(fā)者(可能大部分是使用MySQL的)都沒有受過有關(guān)數(shù)據(jù)庫的正規(guī)培訓(xùn),盡管他們都為客戶做過一些開發(fā),但卻對(duì)如何為數(shù)據(jù)庫建立適當(dāng)?shù)乃饕^少,因此我起了寫一篇相關(guān)文章的念頭。最普通的情況,是為出現(xiàn)在where子句的字段建一個(gè)索引。為方便講述,我們先建立一個(gè)如下的表。CREATETABLEmytable(idserialprimarykey,category_idintnotnulldefault0,user_idintnotnulldefault0,adddateintnotnulldefault0);很簡單吧,不過對(duì)于要說明這個(gè)問題,已經(jīng)足夠了。如果你在查詢時(shí)常用類似以下的語句:SELECT*FROMmytableWHEREcategory_id=1;最直接的應(yīng)對(duì)之道,是為category_id建立一個(gè)簡單的索引:CREATEINDEXmytable_categoryidONmytable(category_id);OK,搞定?先別高興,如果你有不止一個(gè)選擇條件呢?例如:SELECT*FROMmytableWHEREcategory_id=1ANDuser_id=2;你的第一反應(yīng)可能是,再給user_id建立一個(gè)索引。不好,這不是一個(gè)最佳的方法。你可以建立多重的索引。CREATEINDEXmytable_categoryid_useridONmytable(category_id,user_id);注意到我在命名時(shí)的習(xí)慣了嗎?我使用"表名_字段1名_字段2名"的方式。你很快就會(huì)知道我為什么這樣做了?,F(xiàn)在你已經(jīng)為適當(dāng)?shù)淖侄谓⒘怂饕?,不過,還是有點(diǎn)不放心吧,你可能會(huì)問,數(shù)據(jù)庫會(huì)真正用到這些索引嗎?測試一下就OK,對(duì)于大多數(shù)的數(shù)據(jù)庫來說,這是很容易的,只要使用EXPLAIN命令:EXPLAINSELECT*FROMmytableWHEREcategory_id=1ANDuser_id=2;ThisiswhatPostgres7.1returns(exactlyasIexpected)NOTICE:QUERYPLAN:IndexScanusingmytable_categoryid_useridonmytable(cost=0.00..2.02rows=1width=16)EXPLAIN以上是postgres的數(shù)據(jù),可以看到該數(shù)據(jù)庫在查詢的時(shí)候使用了一個(gè)索引(一個(gè)好開始),而且它使用的是我創(chuàng)建的第二個(gè)索引??吹轿疑厦婷暮锰幜税?,你馬上知道它使用適當(dāng)?shù)乃饕?。接著,來個(gè)稍微復(fù)雜一點(diǎn)的,如果有個(gè)ORDERBY字句呢?不管你信不信,大多數(shù)的數(shù)據(jù)庫在使用orderby的時(shí)候,都將會(huì)從索引中受益。SELECT*FROMmytableWHEREcategory_id=1ANDuser_id=2ORDERBYadddateDESC;有點(diǎn)迷惑了吧?很簡單,就象為where字句中的字段建立一個(gè)索引一樣,也為ORDERBY的字句中的字段建立一個(gè)索引:CREATEINDEXmytable_categoryid_userid_adddateONmytable(category_id,user_id,adddate);注意:"mytable_categoryid_userid_adddate”將會(huì)被截短為"mytable_categoryid_userid_addda"CREATEEXPLAINSELECT*FROMmytableWHEREcategory_id=1ANDuser_id=2ORDERBYadddateDESC;NOTICE:QUERYPLAN:Sort(cost=2.03..2.03rows=1width=16)->IndexScanusingmytable_categoryid_userid_adddaonmytable(cost=0.00..2.02rows=1width=16)看看EXPLAIN的輸出,好象有點(diǎn)恐怖啊,數(shù)據(jù)庫多做了一個(gè)我們沒有要求的排序,這下知道性能如何受損了吧,看來我們對(duì)于數(shù)據(jù)庫的自身運(yùn)作是有點(diǎn)過于樂觀了,那么,給數(shù)據(jù)庫多一點(diǎn)提示吧。為了跳過排序這一步,我們并不需要其它另外的索引,只要將查詢語句稍微改一下。這里用的是postgres,我們將給該數(shù)據(jù)庫一個(gè)額外的提示--在ORDERBY語句中,加入where語句中的字段。這只是一個(gè)技術(shù)上的處理,并不是必須的,因?yàn)閷?shí)際上在另外兩個(gè)字段上,并不會(huì)有任何的排序操作,不過如果加入,postgres將會(huì)知道哪些是它應(yīng)該做的。EXPLAINSELECT*FROMmytableWHEREcategory_id=1ANDuser_id=2ORDERBYcategory_idDESC,user_idDESC,adddateDESC;NOTICE:QUERYPLAN:IndexScanBackwardusingmytable_categoryid_userid_adddaonmytable(cost=0.00..2.02rows=1width=16)EXPLAIN現(xiàn)在使用我們料想的索引了,而且它還挺聰明,知道可以從索引后面開始讀,從而避免了任何的排序。以上說得細(xì)了一點(diǎn),不過如果你的數(shù)據(jù)庫非常巨大,并且每日的頁面請(qǐng)求達(dá)上百萬算,我想你會(huì)獲益良多的。不過,如果你要做更為復(fù)雜的查詢呢,例如將多張表結(jié)合起來查詢,特別是where限制字句中的字段是來自不止一個(gè)表格時(shí),應(yīng)該怎樣處理呢?我通常都盡量避免這種做法,因?yàn)檫@樣數(shù)據(jù)庫要將各個(gè)表中的東西都結(jié)合起來,然后再排除那些不合適的行,搞不好開銷會(huì)很大。如果不能避免,你應(yīng)該查看每張要結(jié)合起來的表,并且使用以上的策略來建立索引,然后再用EXPLAIN命令驗(yàn)證一下是否使用了你料想中的索引。如果是的話,就OK。不是的話,你可能要建立臨時(shí)的表來將他們結(jié)合在一起,并且使用適當(dāng)?shù)乃饕?。要注意的是,建立太多的索引將?huì)影響更新和插入的速度,因?yàn)樗枰瑯痈旅總€(gè)索引文件。對(duì)于一個(gè)經(jīng)常需要更新和插入的表格,就沒有必要為一個(gè)很少使用的where字句單獨(dú)建立索引了,對(duì)于比較小的表,排序的開銷不會(huì)很大,也沒有必要建立另外的索引。以上介紹的只是一些十分基本的東西,其實(shí)里面的學(xué)問也不少,單憑EXPLAIN我們是不能判定該方法是否就是最優(yōu)化的,每個(gè)數(shù)據(jù)庫都有自己的一些優(yōu)化器,雖然可能還不太完善,但是它們都會(huì)在查詢時(shí)對(duì)比過哪種方式較快,在某些情況下,建立索引的話也未必會(huì)快,例如索引放在一個(gè)不連續(xù)的存儲(chǔ)空間時(shí),這會(huì)增加讀磁盤的負(fù)擔(dān),因此,哪個(gè)是最優(yōu),應(yīng)該通過實(shí)際的使用環(huán)境來檢驗(yàn)。在剛開始的時(shí)候,如果表不大,沒有必要作索引,我的意見是在需要的時(shí)候才作索引,也可用一些命令來優(yōu)化表,例如MySQL可用"OPTIMIZETABLE"。綜上所述,在如何為數(shù)據(jù)庫建立恰當(dāng)?shù)乃饕矫?,你?yīng)該有一些基本的概念了。數(shù)據(jù)庫設(shè)計(jì)中的14個(gè)技巧原始單據(jù)與實(shí)體之間的關(guān)系可以是一對(duì)一、一對(duì)多、多對(duì)多的關(guān)系。在一般情況下,它們是一對(duì)一的關(guān)系:即一張?jiān)紗螕?jù)對(duì)應(yīng)且只對(duì)應(yīng)一個(gè)實(shí)體。在特殊情況下,它們可能是一對(duì)多或多對(duì)一的關(guān)系,即一張?jiān)紗螕?jù)對(duì)應(yīng)多個(gè)實(shí)體,或多張?jiān)紗螕?jù)對(duì)應(yīng)一個(gè)實(shí)體。這里的實(shí)體可以理解為基本表。明確這種對(duì)應(yīng)關(guān)系后,對(duì)我們?cè)O(shè)計(jì)錄入界面大有好處?!祭?〗:一份員工履歷資料,在人力資源信息系統(tǒng)中,就對(duì)應(yīng)三個(gè)基本表:員工基本情況表、社會(huì)關(guān)系表、工作簡歷表。這就是“一張?jiān)紗螕?jù)對(duì)應(yīng)多個(gè)實(shí)體”的典型例子。主鍵與外鍵一般而言,一個(gè)實(shí)體不能既無主鍵又無外鍵。在E—R圖中,處于葉子部位的實(shí)體,可以定義主鍵,也可以不定義主鍵(因?yàn)樗鼰o子孫),但必須要有外鍵(因?yàn)樗懈赣H)。主鍵與外鍵的設(shè)計(jì),在全局?jǐn)?shù)據(jù)庫的設(shè)計(jì)中,占有重要地位。當(dāng)全局?jǐn)?shù)據(jù)庫的設(shè)計(jì)完成以后,有個(gè)美國數(shù)據(jù)庫設(shè)計(jì)專家說:“鍵,到處都是鍵,除了鍵之外,什么也沒有”,這就是他的數(shù)據(jù)庫設(shè)計(jì)經(jīng)驗(yàn)之談,也反映了他對(duì)信息系統(tǒng)核心(數(shù)據(jù)模型)的高度抽象思想。因?yàn)椋褐麈I是實(shí)體的高度抽象,主鍵與外鍵的配對(duì),表示實(shí)體之間的連接?;颈淼男再|(zhì)基本表與中間表、臨時(shí)表不同,因?yàn)樗哂腥缦滤膫€(gè)特性:(1)原子性?;颈碇械淖侄问遣豢稍俜纸獾?。(2)原始性?;颈碇械挠涗浭窃紨?shù)據(jù)(基礎(chǔ)數(shù)據(jù))的記錄。(3)演繹性。由基本表與代碼表中的數(shù)據(jù),可以派生出所有的輸出數(shù)據(jù)。(4)穩(wěn)定性?;颈淼慕Y(jié)構(gòu)是相對(duì)穩(wěn)定的,表中的記錄是要長期保存的。理解基本表的性質(zhì)后,在設(shè)計(jì)數(shù)據(jù)庫時(shí),就能將基本表與中間表、臨時(shí)表區(qū)分開來。范式標(biāo)準(zhǔn)基本表及其字段之間的關(guān)系,應(yīng)盡量滿足第三范式。但是,滿足第三范式的數(shù)據(jù)庫設(shè)計(jì),往往不是最好的設(shè)計(jì)。為了提高數(shù)據(jù)庫的運(yùn)行效率,常常需要降低范式標(biāo)準(zhǔn):適當(dāng)增加冗余,達(dá)到以空間換時(shí)間的目的?!祭?〗:有一張存放商品的基本表,如表1所示?!敖痤~”這個(gè)字段的存在,表明該表的設(shè)計(jì)不滿足第三范式,因?yàn)椤敖痤~”可以由“單價(jià)”乘以“數(shù)量”得到,說明“金額”是冗余字段。但是,增加“金額”這個(gè)冗余字段,可以提高查詢統(tǒng)計(jì)的速度,這就是以空間換時(shí)間的作法。在Rose2002中,規(guī)定列有兩種類型:數(shù)據(jù)列和計(jì)算列?!敖痤~”這樣的列被稱為“計(jì)算列”,而“單價(jià)”和“數(shù)量”這樣的列被稱為“數(shù)據(jù)列”。表1商品表的表結(jié)構(gòu)商品名稱商品型號(hào)單價(jià)數(shù)量金額電視機(jī)29口寸2,50040100,000通俗地理解三個(gè)范式通俗地理解三個(gè)范式,對(duì)于數(shù)據(jù)庫設(shè)計(jì)大有好處。在數(shù)據(jù)庫設(shè)計(jì)中,為了更好地應(yīng)用三個(gè)范式,就必須通俗地理解三個(gè)范式(通俗地理解是夠用的理解,并不是最科學(xué)最準(zhǔn)確的理解):第一范式:1NF是對(duì)屬性的原子性約束,要求屬性具有原子性,不可再分解;第二范式:2NF是對(duì)記錄的惟一性約束,要求記錄有惟一標(biāo)識(shí),即實(shí)體的惟一性;第三范式:3NF是對(duì)字段冗余性的約束,即任何字段不能由其他字段派生出來,它要求字段沒有冗余。沒有冗余的數(shù)據(jù)庫設(shè)計(jì)可以做到。但是,沒有冗余的數(shù)據(jù)庫未必是最好的數(shù)據(jù)庫,有時(shí)為了提高運(yùn)行效率,就必須降低范式標(biāo)準(zhǔn),適當(dāng)保留冗余數(shù)據(jù)。具體做法是:在概念數(shù)據(jù)模型設(shè)計(jì)時(shí)遵守第三范式,降低范式標(biāo)準(zhǔn)的工作放到物理數(shù)據(jù)模型設(shè)計(jì)時(shí)考慮。降低范式就是增加字段,允許冗余。要善于識(shí)別與正確處理多對(duì)多的關(guān)系若兩個(gè)實(shí)體之間存在多對(duì)多的關(guān)系,則應(yīng)消除這種關(guān)系。消除的辦法是,在兩者之間增加第三個(gè)實(shí)體。這樣,原來一個(gè)多對(duì)多的關(guān)系,現(xiàn)在變?yōu)閮蓚€(gè)一對(duì)多的關(guān)系。要將原來兩個(gè)實(shí)體的屬性合理地分配到三個(gè)實(shí)體中去。這里的第三個(gè)實(shí)體,實(shí)質(zhì)上是一個(gè)較復(fù)雜的關(guān)系,它對(duì)應(yīng)一張基本表。一般來講,數(shù)據(jù)庫設(shè)計(jì)工具不能識(shí)別多對(duì)多的關(guān)系,但能處理多對(duì)多的關(guān)系。〖例3〗:在“圖書館信息系統(tǒng)”中,“圖書”是一個(gè)實(shí)體,“讀者”也是一個(gè)實(shí)體。這兩個(gè)實(shí)體之間的關(guān)系,是一個(gè)典型的多對(duì)多關(guān)系:一本圖書在不同時(shí)間可以被多個(gè)讀者借閱,一個(gè)讀者又可以借多本圖書。為此,要在二者之間增加第三個(gè)實(shí)體,該實(shí)體取名為“借還書”,它的屬性為:借還時(shí)間、借還標(biāo)志(0表示借書,1表示還書),另外,它還應(yīng)該有兩個(gè)外鍵(“圖書”的主鍵,“讀者”的主鍵),使它能與“圖書”和“讀者”連接。主鍵PK的取值方法PK是供程序員使用的表間連接工具,可以是一無物理意義的數(shù)字串,由程序自動(dòng)加1來實(shí)現(xiàn)。也可以是有物理意義的字段名或字段名的組合。不過前者比后者好。當(dāng)PK是字段名的組合時(shí),建議字段的個(gè)數(shù)不要太多,多了不但索引占用空間大,而且速度也慢。正確認(rèn)識(shí)數(shù)據(jù)冗余主鍵與外鍵在多表中的重復(fù)出現(xiàn),不屬于數(shù)據(jù)冗余,這個(gè)概念必須清楚,事實(shí)上有許多人還不清楚。非鍵字段的重復(fù)出現(xiàn),才是數(shù)據(jù)冗余!而且是一種低級(jí)冗余,即重復(fù)性的冗余。高級(jí)冗余不是字段的重復(fù)出現(xiàn),而是字段的派生出現(xiàn)。〖例4〗:商品中的“單價(jià)、數(shù)量、金額”三個(gè)字段,“金額”就是由“單價(jià)”乘以“數(shù)量”派生出來的,它就是冗余,而且是一種高級(jí)冗余。冗余的目的是為了提高處理速度。只有低級(jí)冗余才會(huì)增加數(shù)據(jù)的不一致性,因?yàn)橥粩?shù)據(jù),可能從不同時(shí)間、地點(diǎn)、角色上多次錄入。因此,我們提倡高級(jí)冗余(派生性冗余),反對(duì)低級(jí)冗余(重復(fù)性冗余)。E-R圖沒有標(biāo)準(zhǔn)答案信息系統(tǒng)的E-R圖沒有標(biāo)準(zhǔn)答案,因?yàn)樗脑O(shè)計(jì)與畫法不是惟一的,只要它覆蓋了系統(tǒng)需求的業(yè)務(wù)范圍和功能內(nèi)容,就是可行的。反之要修改E-R圖。盡管它沒有惟一的標(biāo)準(zhǔn)答案,并不意味著可以隨意設(shè)計(jì)。好的E-圖的標(biāo)準(zhǔn)是:結(jié)構(gòu)清晰、關(guān)聯(lián)簡潔、實(shí)體個(gè)數(shù)適中、屬性分配合理、沒有低級(jí)冗余。視圖技術(shù)在數(shù)據(jù)庫設(shè)計(jì)中很有用與基本表、代碼表、中間表不同,視圖是一種虛表,它依賴數(shù)據(jù)源的實(shí)表而存在。視圖是供程序員使用數(shù)據(jù)庫的一個(gè)窗口,是基表數(shù)據(jù)綜合的一種形式,是數(shù)據(jù)處理的一種方法,是用戶數(shù)據(jù)保密的一種手段。為了進(jìn)行復(fù)雜處理、提高運(yùn)算速度和節(jié)省存儲(chǔ)空間,視圖的定義深度一般不得超過三層。若三層視圖仍不夠用,則應(yīng)在視圖上定義臨時(shí)表,在臨時(shí)表上再定義視圖。這樣反復(fù)交迭定義,視圖的深度就不受限制了。對(duì)于某些與國家政治、經(jīng)濟(jì)、技術(shù)、軍事和安全利益有關(guān)的信息系統(tǒng),視圖的作用更加重要。這些系統(tǒng)的基本表完成物理設(shè)計(jì)之后,立即在基本表上建立第一層視圖,這層視圖的個(gè)數(shù)和結(jié)構(gòu),與基本表的個(gè)數(shù)和結(jié)構(gòu)是完全相同。并且規(guī)定,所有的程序員,一律只準(zhǔn)在視圖上操作。只有數(shù)據(jù)庫管理員,帶著多個(gè)人員共同掌握的“安全鑰匙”,才能直接在基本表上操作。請(qǐng)讀者想想:這是為什么?中間表、報(bào)表和臨時(shí)表中間表是存放統(tǒng)計(jì)數(shù)據(jù)的表,它是為數(shù)據(jù)倉庫、輸出報(bào)表或查詢結(jié)果而設(shè)計(jì)的,有時(shí)它沒有主鍵與外鍵(數(shù)據(jù)倉庫除外)。臨時(shí)表是程序員個(gè)人設(shè)計(jì)的,存放臨時(shí)記錄,為個(gè)人所用?;砗椭虚g表由DBA維護(hù),臨時(shí)表由程序員自己用程序自動(dòng)維護(hù)。完整性約束表現(xiàn)在三個(gè)方面域的完整性:用Check來實(shí)現(xiàn)約束,在數(shù)據(jù)庫設(shè)計(jì)工具中,對(duì)字段的取值范圍進(jìn)行定義時(shí),有一個(gè)Check按鈕,通過它定義字段的值城。參照完整性:用PK、FK、表級(jí)觸發(fā)器來實(shí)現(xiàn)。用戶定義完整性:它是一些業(yè)務(wù)規(guī)則,用存儲(chǔ)過程和觸發(fā)器來實(shí)現(xiàn)。防止數(shù)據(jù)庫設(shè)計(jì)打補(bǔ)丁的方法是“三少原則”一個(gè)數(shù)據(jù)庫中表的個(gè)數(shù)越少越好。只有表的個(gè)數(shù)少了,才能說明系統(tǒng)的E—R圖少而精,去掉了重復(fù)的多余的實(shí)體,形成了對(duì)客觀世界的高度抽象,進(jìn)行了系統(tǒng)的數(shù)據(jù)集成,防止了打補(bǔ)丁式的設(shè)計(jì);一個(gè)表中組合主鍵的字段個(gè)數(shù)越少越好。因?yàn)橹麈I的作用,一是建主鍵索引,二是做為子表的外鍵,所以組合主鍵的字段個(gè)數(shù)少了,不僅節(jié)省了運(yùn)行時(shí)間,而且節(jié)省了索引存儲(chǔ)空間;一個(gè)表中的字段個(gè)數(shù)越少越好。只有字段的個(gè)數(shù)少了,才能說明在系統(tǒng)中不存在數(shù)據(jù)重復(fù),且很少有數(shù)據(jù)冗余,更重要的是督促讀者學(xué)會(huì)“列變行”,這樣就防止了將子表中的字段拉入到主表中去,在主表中留下許多空余的字段。所謂“列變行”,就是將主表中的一部分內(nèi)容拉出去,另外單獨(dú)建一個(gè)子表。這個(gè)方法很簡單,有的人就是不習(xí)慣、不采納、不執(zhí)行。數(shù)據(jù)庫設(shè)計(jì)的實(shí)用原則是:在數(shù)據(jù)冗余和處理速度之間找到合適的平衡點(diǎn)?!叭佟笔且粋€(gè)整體概念,綜合觀點(diǎn),不能孤立某一個(gè)原則。該原則是相對(duì)的,不是絕對(duì)的?!叭唷痹瓌t肯定是錯(cuò)誤的。試想:若覆蓋系統(tǒng)同樣的功能,一百個(gè)實(shí)體(共一千個(gè)屬性)的E—R圖,肯定比二百個(gè)實(shí)體(共二千個(gè)屬性)的E—R圖,要好得多。提倡“三少”原則,是叫讀者學(xué)會(huì)利用數(shù)據(jù)庫設(shè)計(jì)技術(shù)進(jìn)行系統(tǒng)的數(shù)據(jù)集成。數(shù)據(jù)集成的步驟是將文件系統(tǒng)集成為應(yīng)用數(shù)據(jù)庫,將應(yīng)用數(shù)據(jù)庫集成為主題數(shù)據(jù)庫,將主題數(shù)據(jù)庫集成為全局綜合數(shù)據(jù)庫。集成的程度越高,數(shù)據(jù)共享性就越強(qiáng),信息孤島現(xiàn)象就越少,整個(gè)企業(yè)信息系統(tǒng)的全局E-R圖中實(shí)體的個(gè)數(shù)、主鍵的個(gè)數(shù)、屬性的個(gè)數(shù)就會(huì)越少。提倡“三少”原則的目的,是防止讀者利用打補(bǔ)丁技術(shù),不斷地對(duì)數(shù)據(jù)庫進(jìn)行增刪改,使企業(yè)數(shù)據(jù)庫變成了隨意設(shè)計(jì)數(shù)據(jù)庫表的“垃圾堆”,或數(shù)據(jù)庫表的“大雜院”,最后造成數(shù)據(jù)庫中的基本表、代碼表、中間表、臨時(shí)表雜亂無章,不計(jì)其數(shù),導(dǎo)致企事業(yè)單位的信息系統(tǒng)無法維護(hù)而癱瘓?!叭唷痹瓌t任何人都可以做到,該原則是“打補(bǔ)丁方法”設(shè)計(jì)數(shù)據(jù)庫的歪理學(xué)說。“三少”原則是少而精的原則,它要求有較高的數(shù)據(jù)庫設(shè)計(jì)技巧與藝術(shù),不是任何人都能做到的,因?yàn)樵撛瓌t是杜絕用“打補(bǔ)丁方法”設(shè)計(jì)數(shù)據(jù)庫的理論依據(jù)。提高數(shù)據(jù)庫運(yùn)行效率的辦法在給定的系統(tǒng)硬件和系統(tǒng)軟件條件下,提高數(shù)據(jù)庫系統(tǒng)的運(yùn)行效率的辦法是:在數(shù)據(jù)庫物理設(shè)計(jì)時(shí),降低范式,增加冗余,少用觸發(fā)器,多用存儲(chǔ)過程。當(dāng)計(jì)算非常復(fù)雜、而且記錄條數(shù)非常巨大時(shí)(例如一千萬條),復(fù)雜計(jì)算要先在數(shù)據(jù)庫外面,以文件系統(tǒng)方式用C++語言計(jì)算處理完成之后,最后才入庫追加到表中去。這是電信計(jì)費(fèi)系統(tǒng)設(shè)計(jì)的經(jīng)驗(yàn)。發(fā)現(xiàn)某個(gè)表的記錄太多,例如超過一千萬條,則要對(duì)該表進(jìn)行水平分割。水平分割的做法是,以該表主鍵PK的某個(gè)值為界線,將該表的記錄水平分割為兩個(gè)表。若發(fā)現(xiàn)某個(gè)表的字段太多,例如超過八十個(gè),則垂直分割該表,將原來的一個(gè)表分解為兩個(gè)表。對(duì)數(shù)據(jù)庫管理系統(tǒng)DBMS進(jìn)行系統(tǒng)優(yōu)化,即優(yōu)化各種系統(tǒng)參數(shù),如緩沖區(qū)個(gè)數(shù)。在使用面向數(shù)據(jù)的SQL語言進(jìn)行程序設(shè)計(jì)時(shí),盡量采取優(yōu)化算法。總之,要提高數(shù)據(jù)庫的運(yùn)行效率,必須從數(shù)據(jù)庫系統(tǒng)級(jí)優(yōu)化、數(shù)據(jù)庫設(shè)計(jì)級(jí)優(yōu)化、程序?qū)崿F(xiàn)級(jí)優(yōu)化,這三個(gè)層次上同時(shí)下功夫。一種邏輯層次連接的工程數(shù)據(jù)庫設(shè)計(jì)方法及應(yīng)用1引言工程數(shù)據(jù)庫系統(tǒng)和傳統(tǒng)數(shù)據(jù)庫系統(tǒng)一樣,包括工程數(shù)據(jù)庫管理系統(tǒng)和工程數(shù)據(jù)庫設(shè)計(jì)兩方面的內(nèi)容.工程數(shù)據(jù)庫設(shè)計(jì)的主要任務(wù)是在工程數(shù)據(jù)庫管理系統(tǒng)的支持下,按照應(yīng)用的要求,為某一類或某個(gè)工程項(xiàng)目設(shè)計(jì)一個(gè)結(jié)構(gòu)合理、使用方便、效率較高的工程數(shù)據(jù)庫及其應(yīng)用系統(tǒng).數(shù)據(jù)庫設(shè)計(jì)得好,可以使整個(gè)應(yīng)用系統(tǒng)效率高、維護(hù)簡單、使用容易.即使是最佳的應(yīng)用程序,也無法彌補(bǔ)數(shù)據(jù)庫設(shè)計(jì)時(shí)的某些缺陷.這方面的研究包括工程數(shù)據(jù)庫設(shè)計(jì)方法和輔助設(shè)計(jì)工具的研究和開發(fā).本文就工程數(shù)據(jù)庫設(shè)計(jì)中的一些問題進(jìn)行討論,闡述了工程數(shù)據(jù)庫設(shè)計(jì)的基本概念和內(nèi)容,以及工程應(yīng)用領(lǐng)域中數(shù)據(jù)庫設(shè)計(jì)的一些特性,介紹了一種以層次分析為主,以連接關(guān)系為基礎(chǔ),結(jié)合面向?qū)ο蠹夹g(shù)來進(jìn)行工程數(shù)據(jù)庫設(shè)計(jì)的方法及其應(yīng)用.2工程數(shù)據(jù)庫設(shè)計(jì)的特點(diǎn)所謂工程數(shù)據(jù)庫設(shè)計(jì),是指從工程應(yīng)用需要出發(fā),設(shè)計(jì)出一個(gè)工程數(shù)據(jù)庫結(jié)構(gòu)的全過程.它的一個(gè)粗略過程是:首先要對(duì)工程應(yīng)用領(lǐng)域的數(shù)據(jù)進(jìn)行需求分析,綜合整理出被處理對(duì)象的概念.這種概念是獨(dú)立于工程數(shù)據(jù)庫管理系統(tǒng)的,與具體的工程數(shù)據(jù)庫管理系統(tǒng)無關(guān).完成概念設(shè)計(jì)后,再根據(jù)實(shí)際情況進(jìn)行數(shù)據(jù)庫的具體設(shè)計(jì).對(duì)作為集成化CAD/CAM系統(tǒng)基礎(chǔ)的工程數(shù)據(jù)庫系統(tǒng)的設(shè)計(jì),在吸取常規(guī)的設(shè)計(jì)思想同時(shí),還要充分考慮與工程設(shè)計(jì)環(huán)境相關(guān)的一些特點(diǎn),要適應(yīng)工程數(shù)據(jù)處理的需要[1].2.1工程數(shù)據(jù)庫的設(shè)計(jì)目標(biāo)工程數(shù)據(jù)庫設(shè)計(jì)要達(dá)到的基本目標(biāo)是要有效的為集成化應(yīng)用提供所需要的工程數(shù)據(jù),并且使這些工程數(shù)據(jù)具有較高的穩(wěn)定性.具體說,概念設(shè)計(jì)的目標(biāo)就是通過對(duì)應(yīng)用系統(tǒng)的信息需求進(jìn)行描述和綜合,從概念上模擬工程應(yīng)用的信息結(jié)構(gòu),便于用戶理解.邏輯設(shè)計(jì)要產(chǎn)生一個(gè)具有數(shù)據(jù)獨(dú)立性高、冗余度低、數(shù)據(jù)一致性和完整性好等特點(diǎn)的邏輯數(shù)據(jù)結(jié)構(gòu),能滿足并最小覆蓋工程應(yīng)用的數(shù)據(jù)需求;能被工程數(shù)據(jù)庫管理系統(tǒng)所處理.物理設(shè)計(jì)要產(chǎn)生一個(gè)可以有效予以實(shí)現(xiàn)的數(shù)據(jù)庫的物理結(jié)構(gòu),以及與系統(tǒng)軟件、硬件及其分布情況有關(guān)的實(shí)現(xiàn)細(xì)節(jié)的設(shè)計(jì).2.2注重設(shè)計(jì)方法的實(shí)用性為了提高系統(tǒng)資源的利用率,簡化軟件設(shè)計(jì)和數(shù)據(jù)的轉(zhuǎn)換工作,避免系統(tǒng)開發(fā)中人力、物力、財(cái)力上的浪費(fèi),提高系統(tǒng)的生產(chǎn)率,就要考慮到設(shè)計(jì)系統(tǒng)的實(shí)用性.通常數(shù)據(jù)庫設(shè)計(jì)方法學(xué)的理論研究大都著重于一般性,而工程數(shù)據(jù)庫設(shè)計(jì)的實(shí)踐更著重于在具體環(huán)境中的實(shí)用性.因此,一方面以滿足用戶需求作為設(shè)計(jì)的出發(fā)點(diǎn)和歸宿,將信息需求貫穿到數(shù)據(jù)庫設(shè)計(jì)的全過程之中;另一方面,在對(duì)數(shù)據(jù)抽象程度、概念模型級(jí)別、數(shù)據(jù)模式類型以及設(shè)計(jì)工具等方面,要根據(jù)設(shè)計(jì)環(huán)境和目標(biāo),著重其實(shí)際效果來進(jìn)行選擇和確定.2.3工程設(shè)計(jì)過程中的一些特點(diǎn).層次結(jié)構(gòu)設(shè)計(jì)人員開始工程項(xiàng)目或產(chǎn)品的設(shè)計(jì)時(shí),對(duì)設(shè)計(jì)的產(chǎn)品或項(xiàng)目一層一層的將它們分解,將一個(gè)復(fù)雜的問題,分成若干個(gè)簡單問題,從而對(duì)它進(jìn)行求解.如商場CAD設(shè)計(jì)中,也是一種以層次為主的分析設(shè)計(jì)過程:商場可以分為樓層(又稱店堂),在樓層店堂中常包含若干小區(qū),小區(qū)又由配套和構(gòu)件組成.很多實(shí)例表明在一個(gè)工程或一個(gè)產(chǎn)品的設(shè)計(jì)開發(fā)過程中,層次結(jié)構(gòu)化分析是問題求解的基本點(diǎn)..邏輯層次結(jié)構(gòu)隨著分層的深入,層次結(jié)構(gòu)會(huì)向著一種有向圖的形式發(fā)展.因?yàn)槊繉由系淖訄D深度是不完全一致的,有的深有的淺,所以在這種層次結(jié)構(gòu)中,上層除了可以調(diào)用直接的下一層外,還可以調(diào)用其它下層的內(nèi)容,但是下層結(jié)構(gòu)不允許調(diào)用上層,這樣的層次結(jié)構(gòu)稱之為邏輯層次結(jié)構(gòu)..自頂向下與自底向上相結(jié)合的設(shè)計(jì)方法在設(shè)計(jì)過程中,經(jīng)常采用自頂向下逐步求精的設(shè)計(jì)方法.經(jīng)過一步一步的分解完善,到最后才能取得較好的效果,滿足實(shí)際需要.在具體設(shè)計(jì)過程中還要結(jié)合自底向上逐步綜合的方法.如在對(duì)商場CAD設(shè)計(jì)的工程數(shù)據(jù)庫設(shè)計(jì)過程中,在邏輯分析階段中運(yùn)用了自頂向下的設(shè)計(jì)方法;而具體設(shè)計(jì)階段又采用了自底向上的設(shè)計(jì)方法.基于工程設(shè)計(jì)過程中的這些特點(diǎn),在進(jìn)行工程數(shù)據(jù)庫設(shè)計(jì)時(shí),要充分發(fā)揮和利用這些特點(diǎn),使工程數(shù)據(jù)庫的設(shè)計(jì)過程能夠與這些特點(diǎn)密切配合,工程數(shù)據(jù)庫的設(shè)計(jì)應(yīng)包含:需求分析、工程數(shù)據(jù)庫的劃分、概念設(shè)計(jì)、邏輯設(shè)計(jì)與物理設(shè)計(jì)等.而貫穿整個(gè)設(shè)計(jì)過程的中心思想是層次分析的方法.3邏輯層次連接的工程數(shù)據(jù)庫設(shè)計(jì)過程設(shè)計(jì)一個(gè)工程數(shù)據(jù)庫,要考慮工程過程中的一些因素;為了確保工程數(shù)據(jù)庫設(shè)計(jì)的優(yōu)良性,還應(yīng)遵循一定的設(shè)計(jì)步驟.下面就圍繞邏輯層次連接的工程數(shù)據(jù)庫的設(shè)計(jì)過程進(jìn)行討論.3.1需求分析在任何設(shè)計(jì)中,首要的任務(wù)是完成詳盡的需求分析,了解用戶的需要.尤其要注重工程過程的特殊性..充分了解集成系統(tǒng)中各有關(guān)數(shù)據(jù)項(xiàng)工程數(shù)據(jù)庫系統(tǒng)是集成化系統(tǒng)中數(shù)據(jù)共享的基礎(chǔ).在進(jìn)行工程數(shù)據(jù)庫設(shè)計(jì)時(shí),只有充分的了解集成化系統(tǒng)中各應(yīng)用軟件對(duì)共享數(shù)據(jù)的要求,才可能對(duì)工程數(shù)據(jù)庫的設(shè)計(jì)做到比較全面合理..要了解各應(yīng)用系統(tǒng)對(duì)共享數(shù)據(jù)的操作工程數(shù)據(jù)庫不僅要存儲(chǔ)被應(yīng)用系統(tǒng)處理過的數(shù)據(jù)信息,同時(shí)還要為應(yīng)用系統(tǒng)提供被處理的數(shù)據(jù),從而就需要了解各應(yīng)用系統(tǒng)對(duì)數(shù)據(jù)的處理要求.這樣設(shè)計(jì)出來的工程數(shù)據(jù)才會(huì)方便于應(yīng)用系統(tǒng)的使用,提高應(yīng)用系統(tǒng)的處理效率..具有一定的可擴(kuò)充能力設(shè)計(jì)的工程數(shù)據(jù)庫,不僅要滿足當(dāng)前的需要,而且還要考慮到今后的發(fā)展,如擴(kuò)充應(yīng)用系統(tǒng)或增加應(yīng)用系統(tǒng)的處理功能,以適應(yīng)工程應(yīng)用中集成化、網(wǎng)絡(luò)化、開放計(jì)算等發(fā)展的需要.3.2庫的劃分在需求分析的基礎(chǔ)上,要對(duì)工程數(shù)據(jù)庫進(jìn)行劃分,工程數(shù)據(jù)庫要能對(duì)各種不同應(yīng)用系統(tǒng)中的數(shù)據(jù)交換、接口等進(jìn)行集中的描述和管理.為了有效的管理,以及提高集成系統(tǒng)的工作效率,方便各應(yīng)用系統(tǒng)對(duì)數(shù)據(jù)的處理,就需要根據(jù)工程過程中的特點(diǎn)對(duì)工程數(shù)據(jù)庫進(jìn)行必要的劃分,將一個(gè)大系統(tǒng)進(jìn)行分解,使一個(gè)大的工程數(shù)據(jù)庫系統(tǒng)分成若干個(gè)小一點(diǎn)的工程數(shù)據(jù)庫.在集成化的CAD/CAM等系統(tǒng)中,通常有這樣三類設(shè)計(jì)數(shù)據(jù):系統(tǒng)公用的共享數(shù)據(jù);為子系統(tǒng)所共享的項(xiàng)目數(shù)據(jù);以及為單個(gè)應(yīng)用而使用的私有數(shù)據(jù).在工程數(shù)據(jù)庫的設(shè)計(jì)過程中,分別將它們聚集一起,分別形成相應(yīng)數(shù)據(jù)庫.在KJ8920計(jì)算機(jī)的模擬過程中,將數(shù)據(jù)庫劃分成器件庫、物理參數(shù)庫、連接關(guān)系庫等幾個(gè)庫.將數(shù)據(jù)庫這樣劃分后,提高了設(shè)計(jì)數(shù)據(jù)的一致性,方便了統(tǒng)一管理,也減少了數(shù)據(jù)的冗余:2].在商場CAD系統(tǒng)的工程數(shù)據(jù)庫設(shè)計(jì)中,將其分成了圖象庫(保存具有典型風(fēng)格的設(shè)計(jì)圖象)、構(gòu)件庫(構(gòu)件資料)、材料庫、樣板庫、設(shè)計(jì)庫等幾類數(shù)據(jù)庫.將一個(gè)大庫分成幾個(gè)小庫(一個(gè)樣板庫未壓縮數(shù)據(jù)達(dá)200MB)后各個(gè)數(shù)據(jù)庫任務(wù)明確,易于管理和理解.庫劃分好后,要對(duì)每個(gè)庫進(jìn)行設(shè)計(jì).劃分成多庫后,范圍縮小了,而且各庫均有一定的物理意義,與某個(gè)或某些應(yīng)用相關(guān),可作為一個(gè)獨(dú)立的環(huán)境而分別處理;不僅有利于工程數(shù)據(jù)庫的設(shè)計(jì),同時(shí)對(duì)分布式環(huán)境下的工程數(shù)據(jù)處理提供了一種方法和手段.3.3概念設(shè)計(jì)概念設(shè)計(jì)要進(jìn)一步細(xì)化庫的結(jié)構(gòu),使其能滿足應(yīng)用系統(tǒng)的功能和數(shù)據(jù)流程.在概念設(shè)計(jì)階段,采用了層次分析為主,對(duì)象分析為輔的方法.在分層的數(shù)據(jù)庫中,數(shù)據(jù)結(jié)構(gòu)是三維的,除了有數(shù)據(jù)表外增加了表明層次的內(nèi)容;上一層數(shù)據(jù)可展開成更詳細(xì)的下一層的數(shù)據(jù);這樣可以方便地實(shí)現(xiàn)系統(tǒng)需要哪一層的數(shù)據(jù),就能夠提取哪一層的數(shù)據(jù).在商場CAD設(shè)計(jì)中,按店堂、小區(qū)、配套、構(gòu)件等層次構(gòu)成了一個(gè)工程數(shù)據(jù)庫系統(tǒng);在此數(shù)據(jù)庫中可以方便的提取店堂、小區(qū)、配套、構(gòu)件直至整個(gè)商場的任何一層的有關(guān)數(shù)據(jù)(如造價(jià)數(shù)據(jù)).另外在概念設(shè)計(jì)階段還將每個(gè)庫視為由對(duì)象、層次結(jié)構(gòu)、鏈接信息等組成.從抽象的角度看,任何一個(gè)工程對(duì)象都是由一些原子對(duì)象和復(fù)合對(duì)象所構(gòu)成.在這里可定義一些基本概念:定義1.層次對(duì)象(Object).層次對(duì)象是可明確標(biāo)識(shí)的實(shí)體.如商場、店堂、小區(qū)、構(gòu)件等都可視為一種層次對(duì)象.在這里層次對(duì)象具有一定的物理意義,并包含一定的關(guān)系和內(nèi)容.在層次對(duì)象之間,存在著某種關(guān)系,有時(shí)甚至是一種復(fù)雜的有向無循環(huán)圖的關(guān)系.如在一個(gè)店堂中其小區(qū)的分布是交叉的.在一個(gè)服裝商場中常見到,在某一層(店堂)中交叉分布著男士服裝、女士服裝以及兒童服裝等小區(qū).為了處理這種擴(kuò)充了的層次關(guān)系.引進(jìn)了聯(lián)系、連接、關(guān)系等概念.以便能處理工程中的復(fù)雜關(guān)系.定義2.關(guān)系(Relation).關(guān)系表示2個(gè)對(duì)象間的相互依賴,它由一對(duì)連接組成,其中一個(gè)連接的源對(duì)象是另一個(gè)的目的對(duì)象.如構(gòu)件環(huán)行低柜(hd)可以用于化裝品小區(qū)(hzpxq),也可用于煙酒小區(qū)(yjxq),其關(guān)系可以表示為(hd,hzpxq)和(hd,yjxq).定義3.節(jié)點(diǎn)(Node).節(jié)點(diǎn)是一種實(shí)體對(duì)象,一個(gè)節(jié)點(diǎn)由具有相同屬性的一個(gè)或一組實(shí)體構(gòu)成.如環(huán)行低柜構(gòu)件、化裝品小區(qū)、煙酒小區(qū)等都被視為一個(gè)具體的節(jié)點(diǎn).根據(jù)處理的不同,進(jìn)一步將節(jié)點(diǎn)分成兩類,一類是中間節(jié)點(diǎn),另一類為葉節(jié)點(diǎn).中間節(jié)點(diǎn)表明它還有下屬層次,還能進(jìn)一步細(xì)分.而葉節(jié)點(diǎn)則表明,已經(jīng)分到了原子對(duì)象,不能或無需再分.在商場CAD系統(tǒng)中,節(jié)點(diǎn)層為構(gòu)件層,其它層次均視為中間層次.在工程過程中,某對(duì)象所包含的層次數(shù)目可能是不等的,這樣葉節(jié)點(diǎn)所處的層次深度不同.為此設(shè)立了虛節(jié)點(diǎn),虛節(jié)點(diǎn)是為了保證對(duì)象具有同樣的層次深度,這些節(jié)點(diǎn)只起邏輯上的作用,并不包含具體的內(nèi)容.這樣一個(gè)工程數(shù)據(jù)庫可表示為(層Layer,層次對(duì)象Object,關(guān)系Relation);而層次對(duì)象又由節(jié)點(diǎn)和關(guān)系構(gòu)成,即層次對(duì)象Object(節(jié)點(diǎn)Node,關(guān)系Relation)等.3.4邏輯設(shè)計(jì)邏輯設(shè)計(jì)是將概念設(shè)計(jì)所產(chǎn)生的與具體工程數(shù)據(jù)庫管理系統(tǒng)無關(guān)的數(shù)據(jù)模式,轉(zhuǎn)換成以工程數(shù)據(jù)庫的邏輯數(shù)據(jù)模型表示的數(shù)據(jù)模式.理論上任何數(shù)據(jù)庫管理系統(tǒng)都可以用來管理工程數(shù)據(jù).下面以工程數(shù)據(jù)庫管理系統(tǒng)EDBMS為例[3—5],討論工程數(shù)據(jù)庫的邏輯設(shè)計(jì).1)將概念模式中的層轉(zhuǎn)換為EDBMS的表數(shù)據(jù)表可視為一種二維的關(guān)系結(jié)構(gòu).為了實(shí)現(xiàn)擴(kuò)展的層次模型,將概念模型中的每一層作為一個(gè)數(shù)據(jù)表;對(duì)于葉節(jié)點(diǎn)層由于其依附的關(guān)系不同,可分別轉(zhuǎn)換為多個(gè)數(shù)據(jù)表.2)轉(zhuǎn)換實(shí)體對(duì)象為記錄在EDBMS中,由于它是一種面向記錄的模式;對(duì)擴(kuò)展層次模式中的各個(gè)實(shí)體,均將其轉(zhuǎn)換為數(shù)據(jù)記錄,用記錄來表示實(shí)體.3)用連接來表示擴(kuò)展層次模式中的聯(lián)系為了保證擴(kuò)展層次模型中的復(fù)雜關(guān)系.在EDBMS中專門提供了用于建立實(shí)體間聯(lián)系的DDL和DML語言Link族語句,該族語句可以在庫與庫、表與表、表與記錄、記錄與記錄之間建立一對(duì)一、一對(duì)多、以及多對(duì)多的關(guān)系.這樣就將復(fù)雜的聯(lián)系進(jìn)行了描述和處理.3.5物理設(shè)計(jì)物理設(shè)計(jì)的任務(wù)是選擇合適的存儲(chǔ)結(jié)構(gòu)和存取路徑,設(shè)計(jì)的主要目標(biāo)是:提高數(shù)據(jù)庫的性能,尤其要滿足應(yīng)用系統(tǒng)的性能要求;此外還要提高存儲(chǔ)空間的利用率[3].在EDBMS的物理設(shè)計(jì)中,主要目標(biāo)之一是如何提高事務(wù)的處理效率.在物理設(shè)計(jì)時(shí)就要利用EDBMS的特點(diǎn),如Link語句所提供的在復(fù)雜對(duì)象間建立聯(lián)系,通過它可以快速的提取指定的數(shù)據(jù),而無需進(jìn)行數(shù)據(jù)的查找,從而具有較快的數(shù)據(jù)檢索速度.另外EDBMS還提供了多表多記錄的處理方式[5],將一個(gè)庫的多個(gè)表或多條記錄一次加載到內(nèi)存中,從而減少了讀盤的次數(shù),提高了效率.

4邏輯層次連接設(shè)計(jì)方法的應(yīng)用我們已將邏輯層次連接方法應(yīng)用于“工程圖紙管理系統(tǒng)”、“集成化商業(yè)CAD設(shè)計(jì)系統(tǒng)”等,由于它具有關(guān)系/對(duì)象模式的優(yōu)點(diǎn),在數(shù)據(jù)檢索應(yīng)用中有著較高的效率.4.1在工程圖紙管理系統(tǒng)中的應(yīng)用BIDMS作為集成化CAD系統(tǒng)BICAD的一個(gè)子系統(tǒng),是將BICAD系統(tǒng)中產(chǎn)生的設(shè)計(jì)圖紙統(tǒng)一管理起來[6].BIDMS利用圖紙間的層次關(guān)系來組織管理圖紙,已應(yīng)用于建筑領(lǐng)域.不僅減少了各專業(yè)的輸入工作量,提高了工效,消除了因數(shù)據(jù)輸入差錯(cuò)而引起的設(shè)計(jì)錯(cuò)誤和返工現(xiàn)象,而且避免了專業(yè)之間聯(lián)系不夠?qū)е碌摹板e(cuò)、漏、碰”等問題.在組織圖紙時(shí),每個(gè)設(shè)計(jì)項(xiàng)目建一個(gè)庫.每一庫里有專業(yè)表、類表、組表、序表,分別存放專業(yè)、類、組、序的信息.如圖1所示.專業(yè)表、類表、組表中只有專業(yè)號(hào)、類號(hào)、組號(hào)屬性,序表中除了有序號(hào)信息外,還存放圖紙的屬性,如設(shè)計(jì)者,繪圖員、圖名、生成時(shí)間等.專業(yè)表和類表、類表和組表、組表和序表之間建立LINK關(guān)系,即某一專業(yè)(專業(yè)表中的一條記錄)與此專業(yè)的類(類表中的一條記錄)用LINK鏈聯(lián)系起來.同樣類與組,組與序也聯(lián)系起來.這樣,用戶要查看某專業(yè)的第幾張圖,就可通過此表來得到DBK,迅速找到要看的圖.專業(yè)袤類表組表序表專業(yè)號(hào)版本號(hào)LINK專業(yè)袤類表組表序表專業(yè)號(hào)版本號(hào)LINK類號(hào)MNKW號(hào)LINK牖礦圖文件LL4圖名建現(xiàn)結(jié)枸01能y&L牌囊通\\31亨掉水!電氣\\E11J\2&0J7尋L(il,3■1崖筑專業(yè)原序?表4.2在其它方面的應(yīng)用邏輯層次連接的設(shè)計(jì)方法不僅可應(yīng)用于工程數(shù)據(jù)庫的設(shè)計(jì),在其他應(yīng)用中也可以取得較好的效果.如對(duì)某連鎖店的數(shù)據(jù)管理中,以EDBMS為基礎(chǔ),結(jié)合邏輯層次連接的設(shè)計(jì)方法,對(duì)其銷售數(shù)據(jù)進(jìn)行檢索處理.將其處理的結(jié)果與某大型數(shù)據(jù)庫管理系統(tǒng)(未帶加速器情況下)進(jìn)行了比較.比較內(nèi)容有:在銷售數(shù)據(jù)庫中檢索某商品的銷售情況(測試1);在銷售數(shù)據(jù)庫中檢索出沒有銷售的商品種類(測試2).測試的條件分別是:商品數(shù)據(jù)庫4786條記錄,75300條銷售記錄(記為4786/75300);以及商品種類為18603種,銷售記錄252885條(記為18603/252885).其銷售庫的主要結(jié)構(gòu)是:xsrb(xssjdatenotnull,/*銷售日期*/spbmchar(5)notnull,/*商品編碼*/xsslsmallfloat,/*銷售數(shù)量*/xsjemoney(12,2),/□銷售金額*/};其中,某大型數(shù)據(jù)庫系統(tǒng)在商品編碼spbm屬性上建有索引.而商品庫主要結(jié)構(gòu)為:spb{spbmchar(5),/*商品編碼*/spmcchar(20),/*商品名稱*/tmchar(12),/*條碼*/};同樣,某大型數(shù)據(jù)庫系統(tǒng)也在商品編碼spbm屬性上建有索引.而EDBMS未采用索引.其測試結(jié)果如表1所示.其中帶*為某大型數(shù)據(jù)庫系統(tǒng)的測試結(jié)果(其運(yùn)行環(huán)境為PC586,UNIX).EDBMS是在Windows95環(huán)境下進(jìn)行測試的.表1測試結(jié)果測試內(nèi)容4786/7530018602/252885測試159秒*1秒缺*1秒測試2>1小時(shí)*2秒缺*8秒5結(jié)束語工程數(shù)據(jù)庫設(shè)計(jì)的基礎(chǔ)都來自于需求,同時(shí)要切合工程實(shí)際,在高效可行、符合工程人員認(rèn)識(shí)水平并易于運(yùn)用等各方面給予足夠的重視.一個(gè)好的設(shè)計(jì)方法可以提高工程數(shù)據(jù)庫設(shè)計(jì)的質(zhì)量和效率,也是工程數(shù)據(jù)庫系統(tǒng)成功的關(guān)鍵之一.基于邏輯層次連接的工程數(shù)據(jù)庫設(shè)計(jì)模式是從實(shí)踐中總結(jié)出來的,它能有效的提高數(shù)據(jù)檢索效率.作為一種通用的工程數(shù)據(jù)庫設(shè)計(jì)方法還需要更多的面向數(shù)據(jù)庫設(shè)計(jì)的全過程,在實(shí)踐中不斷提高完善.用實(shí)體關(guān)系圖進(jìn)行數(shù)據(jù)庫建模一、概述很可能你現(xiàn)在正在規(guī)劃一個(gè)數(shù)據(jù)庫驅(qū)動(dòng)的網(wǎng)站;而且?guī)缀蹩梢钥隙ǖ氖牵阋欢ㄒ呀?jīng)瀏覽過數(shù)據(jù)庫驅(qū)動(dòng)的網(wǎng)站。過去,一些網(wǎng)站依賴CGI腳本和文本文件存儲(chǔ)實(shí)現(xiàn)數(shù)據(jù)持久化,但現(xiàn)在我們能夠訪問大量不同的關(guān)系型、對(duì)象-關(guān)系型、面向?qū)ο笮蛿?shù)據(jù)庫。對(duì)于Web應(yīng)用來說,關(guān)系數(shù)據(jù)庫是一種強(qiáng)大的支持工具,這得感謝它們的高可用性、性能,而且相對(duì)來說,關(guān)系數(shù)據(jù)庫比較容易使用。要找出一個(gè)功能完善、源代碼開放、能夠在多種平臺(tái)上運(yùn)行的數(shù)據(jù)庫系統(tǒng)并不困難。你可以用Perl、Java、PHP以及其他服務(wù)器端腳本語言把關(guān)系數(shù)據(jù)庫和Web網(wǎng)站連結(jié)到一起。隨著網(wǎng)站規(guī)模的發(fā)展,它對(duì)數(shù)據(jù)庫——通常是關(guān)系數(shù)據(jù)庫一一的依賴程度也日益增加。大量頁面和服務(wù)需要向數(shù)據(jù)庫表寫入信息,或者從數(shù)據(jù)庫提取信息。對(duì)于大多數(shù)網(wǎng)站,數(shù)據(jù)庫表很快成為網(wǎng)站體系結(jié)構(gòu)中的關(guān)鍵部分,成為網(wǎng)站運(yùn)作的生命中樞。為了方便和輕松地管理大容量數(shù)據(jù),用戶帳戶、新聞動(dòng)態(tài)、內(nèi)容、統(tǒng)計(jì)數(shù)據(jù)都可以保存到關(guān)系數(shù)據(jù)庫管理系統(tǒng)(RelationalDatabaseManagementSystem,RDBMS)。用圖(Diagram)管理數(shù)據(jù)模型具有高效、方便的優(yōu)點(diǎn)。對(duì)于RDBMS,描述數(shù)據(jù)模型的圖通常稱為實(shí)體關(guān)系圖(EntityRelationshipDiagram,ERD)。用ERD描述數(shù)據(jù)模型能夠幫助你預(yù)先精確定義數(shù)據(jù)需求,使你能夠?qū)σ院蟮母膭?dòng)作出有效的規(guī)劃,能夠隨著網(wǎng)站的發(fā)展方便地改進(jìn)規(guī)劃。本文將介紹ERD建模工具和概念。文章提供了一些圖的實(shí)例,但它們的目的不是提供精確的或者是全面的數(shù)據(jù)設(shè)計(jì)范例。它們的目的是以兩個(gè)建模工具為例,介紹數(shù)據(jù)建模符號(hào)。在不同的工具之間,圖的符號(hào)有著重大的差別,但它們的基本概念一樣。本文的圖例從PowerDesigner和Visio2000Professional的試用版得到,你可以從本文末尾找到這些工具和其他類似產(chǎn)品的鏈接。二、是否使用建模工具?許多規(guī)模較小的網(wǎng)站用ASCII形式的SQL(StructuredQueryLanguage)腳本文件進(jìn)行數(shù)據(jù)建模。當(dāng)開發(fā)小組人員較少,或者最理想的情況下僅由一個(gè)人構(gòu)成時(shí),這種方法最有效。然而,數(shù)據(jù)模型將很快發(fā)展成為一個(gè)復(fù)雜的結(jié)構(gòu)在這種情況下,CASE(ComputerAidedSoftwareEngineering,計(jì)算機(jī)輔助軟件設(shè)計(jì))工具、有關(guān)所有數(shù)據(jù)信息的圖、集中式知識(shí)庫能夠極大地幫助你管理Web網(wǎng)站的數(shù)據(jù)層。2.1何時(shí)使用SQL?即使當(dāng)你準(zhǔn)備用SQL直接管理數(shù)據(jù)模式(物理數(shù)據(jù)庫)時(shí),圖也能有效地幫助你理解和改進(jìn)系統(tǒng)。然而,如果你的預(yù)算或者時(shí)間非常有限,采用復(fù)雜的新式建模工具可能得不償失。相反,在這種情況下,你應(yīng)該使用一個(gè)簡單的圖形工具把數(shù)據(jù)模式的基本情況記錄下來,然后逐步轉(zhuǎn)換到復(fù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論