版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 小型數(shù)據(jù)庫(kù)</b></p><p> ——命令解析器、數(shù)據(jù)存儲(chǔ)的設(shè)計(jì)與實(shí)現(xiàn)</p><p><b> 摘 要</b></p><p> 當(dāng)今時(shí)代,“數(shù)據(jù)”已經(jīng)成為一種資源。隨著各種數(shù)據(jù)獲取技術(shù)和數(shù)據(jù)庫(kù)技術(shù)的迅速發(fā)展,人們積累的數(shù)據(jù)越來(lái)越多,如何更加合理的管理數(shù)據(jù)顯得更加重要。小型數(shù)據(jù)
2、庫(kù)就是模擬目前比較流行的一些大型數(shù)據(jù)庫(kù),實(shí)現(xiàn)通過(guò)在命令行輸入相應(yīng)命令來(lái)對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ),管理和查詢(xún)。</p><p> 該小型數(shù)據(jù)庫(kù)MyDB包括兩大模塊:SQL命令解析器及數(shù)據(jù)存儲(chǔ)模塊。SQL命令解析器負(fù)責(zé)解析用戶(hù)命令并完成用戶(hù)對(duì)表的創(chuàng)建、刪除、插入、更新等操作;數(shù)據(jù)存儲(chǔ)模塊的主要功能是保存和管理用戶(hù)的數(shù)據(jù)。整個(gè)系統(tǒng)是用C語(yǔ)言、采用模塊化的程序設(shè)計(jì)思想實(shí)現(xiàn)的。</p><p> 關(guān)鍵詞:
3、MyDB;命令解析;數(shù)據(jù)存儲(chǔ);C語(yǔ)言</p><p> Minidatabase</p><p> ---- Design and Implementation of Command Interpreter and Data Storage</p><p><b> Abstract</b></p><p> I
4、n this information era, data has been a kind of resource. With the fast development of data getting technology and database technology, people accumulate more and more data. How to manage these data more rational become
5、more and more important. Minidatabase is to simulate popular database at present and implement data storage, management and querying by inputting commands from command line. </p><p> This Minidatabase ——My
6、DB includes two modules: SQL command parser and data storage. SQL command parser takes in change of parsing user commands and operating tables, such as creating a table, deleting a table, inserting elements into table an
7、d updating table. The primary function of data storage module is to save and manage user data. The whole system is designed with the idea of modularized programmer and developed with C program language.</p><p&
8、gt; Key words: MyDB ; command parse ; data storage ; C program language</p><p><b> 目 錄</b></p><p><b> 論文總頁(yè)數(shù):24頁(yè)</b></p><p><b> 1引言1</b><
9、;/p><p> 1.1數(shù)據(jù)庫(kù)課程教學(xué)的現(xiàn)狀1</p><p> 1.2研制DBMS的重要性1</p><p> 1.3MyDB的設(shè)計(jì)目標(biāo)2</p><p><b> 2數(shù)據(jù)庫(kù)理論2</b></p><p> 2.1數(shù)據(jù)元素的表示2</p><p>
10、;<b> 2.1.1字段2</b></p><p><b> 2.1.2記錄3</b></p><p><b> 2.1.3塊3</b></p><p> 2.2查詢(xún)編譯器3</p><p> 3MyDB的實(shí)現(xiàn)5</p><p>
11、; 3.1記錄的定義5</p><p> 3.2命令解析模塊6</p><p> 3.2.1 詞法分析器7</p><p> 3.2.2 語(yǔ)法分析器11</p><p> 3.2.3 SQL語(yǔ)句的實(shí)現(xiàn)13</p><p> 3.3基本表模塊18</p><p>
12、3.3.1數(shù)據(jù)組織18</p><p> 3.3.2基本表的實(shí)現(xiàn)19</p><p> 3.4數(shù)據(jù)存儲(chǔ)模塊20</p><p><b> 結(jié) 論21</b></p><p><b> 參考文獻(xiàn)21</b></p><p><b> 致 謝
13、23</b></p><p><b> 聲 明24</b></p><p><b> 引言</b></p><p> 數(shù)據(jù)庫(kù)課程教學(xué)的現(xiàn)狀</p><p> 現(xiàn)在數(shù)據(jù)庫(kù)教學(xué)的不足突出地表現(xiàn)在以下幾點(diǎn):</p><p> 1.普遍只強(qiáng)調(diào)理論,不重視實(shí)踐
14、,在學(xué)習(xí)過(guò)程中難以對(duì)概念深刻領(lǐng)悟,課程結(jié)束后就很快把其中許多內(nèi)容給淡忘掉了。</p><p> 2.現(xiàn)有對(duì)數(shù)據(jù)庫(kù)的實(shí)踐也是流于形式,內(nèi)容膚淺與真實(shí)的數(shù)據(jù)庫(kù)管理系統(tǒng)相去甚遠(yuǎn)。比如用SQL語(yǔ)言對(duì)數(shù)據(jù)庫(kù)進(jìn)行一定的創(chuàng)建查詢(xún)操作。這些實(shí)踐都不過(guò)是對(duì)數(shù)據(jù)庫(kù)管理系統(tǒng)的使用,根本談不上了解數(shù)據(jù)庫(kù)本身的運(yùn)行機(jī)理。而且這些實(shí)踐都太過(guò)理想化,完全把底層原理透明化了,這些實(shí)踐充其量只不過(guò)是對(duì)SQL語(yǔ)言熟悉而已。</p>
15、<p> 3.用真實(shí)的數(shù)據(jù)庫(kù)管理系統(tǒng)來(lái)實(shí)踐顯然要好得多。但現(xiàn)實(shí)中的數(shù)據(jù)庫(kù)管理系統(tǒng)都太過(guò)龐大,比如開(kāi)源的數(shù)據(jù)庫(kù)管理系統(tǒng)MYSQL,僅源代碼就達(dá)數(shù)十萬(wàn)行之多。專(zhuān)業(yè)人員閱讀起來(lái)都不會(huì)很容易,更不要說(shuō)剛讀本科的學(xué)生對(duì)其進(jìn)行修改了,所以收效甚微。</p><p> 以上三點(diǎn)明顯地說(shuō)明了:“實(shí)踐”在數(shù)據(jù)庫(kù)原理教學(xué)中的重要性。需要一個(gè)能夠真正對(duì)數(shù)據(jù)庫(kù)所學(xué)理論進(jìn)行有效的實(shí)踐的數(shù)據(jù)庫(kù)管理系統(tǒng)。但缺少一個(gè)好的教學(xué)用數(shù)據(jù)
16、庫(kù)管理系統(tǒng),現(xiàn)有的教學(xué)用數(shù)據(jù)庫(kù)管理系統(tǒng)并不那么適合中國(guó)的實(shí)際情況。</p><p> 因此,無(wú)論是從應(yīng)用的角度還是學(xué)習(xí)數(shù)據(jù)庫(kù)的理論教學(xué)的角度來(lái)看,設(shè)計(jì)與實(shí)現(xiàn)一個(gè)小型的數(shù)據(jù)庫(kù)管理系統(tǒng)都是很有必要的。</p><p> 研制DBMS的重要性</p><p> 數(shù)據(jù)庫(kù)技術(shù)產(chǎn)生于1970年前后。它的出現(xiàn)使得計(jì)算機(jī)的應(yīng)用進(jìn)入了新的時(shí)期,社會(huì)的每個(gè)領(lǐng)域都與計(jì)算機(jī)發(fā)生了聯(lián)系
17、。數(shù)據(jù)庫(kù)技術(shù)聚集了數(shù)據(jù)處理最精華的思想,是管理信息最先進(jìn)的工具。信息社會(huì)的緊迫需求使數(shù)據(jù)庫(kù)技術(shù)成為計(jì)算機(jī)園地中一支最有生命力的新秀。而與人工智能的結(jié)合又使它獲得了新的血液。20世紀(jì)80年代中期數(shù)據(jù)庫(kù)技術(shù)進(jìn)入一個(gè)新的層次,智能數(shù)據(jù)庫(kù)、演繹數(shù)據(jù)庫(kù)、專(zhuān)家數(shù)據(jù)庫(kù)、面向?qū)ο髷?shù)據(jù)庫(kù)、工程數(shù)據(jù)庫(kù)、多介質(zhì)數(shù)據(jù)庫(kù)、并行數(shù)據(jù)庫(kù)、實(shí)時(shí)數(shù)據(jù)庫(kù)等就是當(dāng)代數(shù)據(jù)庫(kù)研究的前沿。</p><p> 數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)的研制是一件非常復(fù)雜
18、的軟件工程。它涉及的面非常廣泛,需要軟件、硬件及設(shè)備方面的知識(shí);需要一定的物質(zhì)條件;需要研制人員的豐富的編程經(jīng)驗(yàn)和精深的軟件技術(shù);需要科學(xué)的管理方法和科學(xué)先進(jìn)的測(cè)試技術(shù)。當(dāng)然由于系統(tǒng)的功能和規(guī)模不一樣,其復(fù)雜程度也相差很大。大一點(diǎn)的數(shù)據(jù)庫(kù)如IMS花費(fèi)幾千人年,系統(tǒng)R的研制花費(fèi)了120個(gè)專(zhuān)家人年以及幾千程序員人年,SYSTEM2000花費(fèi)400人年。數(shù)據(jù)庫(kù)的設(shè)計(jì)與數(shù)據(jù)庫(kù)的設(shè)計(jì)不同,前者屬于系統(tǒng)軟件設(shè)計(jì),與機(jī)器世界比較接近,它的基礎(chǔ)是OS;
19、后者屬于應(yīng)用軟件設(shè)計(jì),與現(xiàn)實(shí)世界更為接近,它的基礎(chǔ)是數(shù)據(jù)庫(kù)。所以數(shù)據(jù)庫(kù)是介于用戶(hù)程序和OS之間的一個(gè)中間媒介,是使得物理數(shù)據(jù)庫(kù)與用戶(hù)程序相互獨(dú)立的軟件系統(tǒng)。</p><p> 研制數(shù)據(jù)庫(kù)對(duì)于從事數(shù)據(jù)庫(kù)開(kāi)發(fā)的科研人員和教學(xué)人員是一件十分有價(jià)值的工作。通過(guò)參加研制數(shù)據(jù)庫(kù)的工作,可以加深對(duì)數(shù)據(jù)庫(kù)技術(shù)的理解,弄清其來(lái)龍去脈,提高技術(shù)水平,從而改進(jìn)數(shù)據(jù)庫(kù)教學(xué)質(zhì)量。更重要的是滿(mǎn)足社會(huì)需求。同時(shí)數(shù)據(jù)庫(kù)的研制是一件很基礎(chǔ)的工作
20、,是研究面向?qū)ο髷?shù)據(jù)庫(kù)、分布式數(shù)據(jù)庫(kù)、知識(shí)庫(kù)以及智能數(shù)據(jù)庫(kù)的基礎(chǔ)。因此,數(shù)據(jù)庫(kù)原理一般都作為計(jì)算機(jī)專(zhuān)業(yè)的基礎(chǔ)課程學(xué)習(xí)。</p><p><b> MyDB的設(shè)計(jì)目標(biāo)</b></p><p> 先看看國(guó)際上有關(guān)數(shù)據(jù)庫(kù)發(fā)展的情況。隨著計(jì)算機(jī)廣泛而深入地應(yīng)用與社會(huì)各行各業(yè),作為其中重要支柱的系統(tǒng)軟件——數(shù)據(jù)庫(kù)變的越來(lái)越龐大,功能越來(lái)越強(qiáng),而且這種發(fā)展勢(shì)頭絲毫不見(jiàn)有放慢的
21、跡象。特別是隨著網(wǎng)絡(luò)通信技術(shù)的發(fā)展,現(xiàn)代主流的數(shù)據(jù)庫(kù)廠商紛紛把網(wǎng)絡(luò)特性集成系統(tǒng)之中,甚至還出現(xiàn)了專(zhuān)門(mén)應(yīng)用于網(wǎng)絡(luò)環(huán)境的分布式數(shù)據(jù)庫(kù)管理系統(tǒng)。所有這些數(shù)據(jù)庫(kù)的復(fù)雜性給數(shù)據(jù)庫(kù)的設(shè)計(jì)帶來(lái)很大的挑戰(zhàn)。</p><p> 如果個(gè)人想設(shè)計(jì)并實(shí)現(xiàn)一個(gè)商用的數(shù)據(jù)庫(kù)基本上是不可能的,復(fù)雜的技術(shù)細(xì)節(jié)會(huì)把數(shù)據(jù)庫(kù)的最基本的理論完全掩蓋。因此,學(xué)生很難通過(guò)商用的數(shù)據(jù)庫(kù)學(xué)習(xí)數(shù)據(jù)庫(kù)的原理。MyDB是一個(gè)面向教學(xué)用的DBMS,這是必須首先堅(jiān)持的
22、,同時(shí)亦對(duì)DBMS的存儲(chǔ)管理、SQL語(yǔ)言感興趣。</p><p> 總之,MyDB是一個(gè)基于關(guān)系代數(shù)的、用C實(shí)現(xiàn)的、面向教學(xué)的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)。</p><p><b> 數(shù)據(jù)庫(kù)理論</b></p><p><b> 數(shù)據(jù)元素的表示</b></p><p> 首先,研究一下最基本的數(shù)據(jù)元
23、素的表示,即關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)中的屬性值的表示。這是用“字段”來(lái)表示的。然后,考察字段如何組裝成存儲(chǔ)系統(tǒng)中更大的元素:記錄、塊和文件</p><p><b> 字段</b></p><p> 屬性需要用定長(zhǎng)或變長(zhǎng)的字節(jié)序列表示,稱(chēng)作“字段”;</p><p> 可以用下式所示的CREATE TABLE 語(yǔ)句在SQL系統(tǒng)中聲明一個(gè)關(guān)系。數(shù)據(jù)庫(kù)負(fù)
24、責(zé)表示和存儲(chǔ)由這個(gè)定義描述的關(guān)系。既然關(guān)系是元組的集合,元組與記錄或“結(jié)構(gòu)”(C或C++術(shù)語(yǔ))相似,可以設(shè)想每一個(gè)元組在磁盤(pán)中作為一條記錄來(lái)存儲(chǔ)。記錄會(huì)占據(jù)某個(gè)磁盤(pán)塊(或一部分),在記錄內(nèi)部,對(duì)應(yīng)于關(guān)系的每一個(gè)屬性有一個(gè)字段。</p><p> CREATE TABLE StudentInfor</p><p><b> ?。?lt;/b></p><
25、p> number int ,</p><p> name CHAR(6) ,</p><p><b> age int ,</b></p><p> address CHAR(20) ,</p><p><b> ……</b></p><p><b&g
26、t; ?。?lt;/b></p><p><b> 記錄</b></p><p> 字段被組裝成定長(zhǎng)或變長(zhǎng)的集合,成為“記錄”;</p><p><b> 定長(zhǎng)記錄的構(gòu)造</b></p><p> 元組由記錄表示,而記錄由上述所討論的各種字段組成。最簡(jiǎn)單的情況是記錄的所有字段均為定長(zhǎng),
27、則可以將字段連接成記錄。</p><p><b> 記錄首部</b></p><p> 當(dāng)設(shè)計(jì)記錄的格式的時(shí)候,必然會(huì)引出另一個(gè)問(wèn)題:通常在記錄中需要保存一些信息,而這些信息不是任何字段的值。因此有必要在記錄的首部添加相關(guān)信息,如:記錄長(zhǎng)度、字段數(shù)等。</p><p><b> 塊</b></p>&l
28、t;p> 構(gòu)成一個(gè)關(guān)系或類(lèi)的外延的記錄集存儲(chǔ)為塊的集合,成為文件。</p><p><b> 查詢(xún)編譯器</b></p><p> 查詢(xún)處理器需采取三個(gè)主要步驟:</p><p> 1)對(duì)使用諸如SQL的某種語(yǔ)言書(shū)寫(xiě)的查詢(xún)進(jìn)行語(yǔ)法分析,亦即將查詢(xún)語(yǔ)句轉(zhuǎn)換成按某種有用方式表示查詢(xún)語(yǔ)句結(jié)構(gòu)的語(yǔ)法樹(shù);</p><p&
29、gt; 2)把語(yǔ)法分析樹(shù)轉(zhuǎn)換成代數(shù)關(guān)系表達(dá)式樹(shù)(或某種類(lèi)似標(biāo)記),稱(chēng)之為邏輯查詢(xún)計(jì)劃;</p><p> 3)邏輯查詢(xún)計(jì)劃需轉(zhuǎn)換成物理查詢(xún)計(jì)劃,物理查詢(xún)計(jì)劃不僅指名了要執(zhí)行的操作,而且也找出了這些操作執(zhí)行的順序、執(zhí)行每步所用的算法、獲得所存儲(chǔ)數(shù)據(jù)的方式以及數(shù)據(jù)從一個(gè)操作傳遞給另一個(gè)操作的方式。</p><p> 查詢(xún)編譯的開(kāi)始幾個(gè)階段如圖所示:</p><p>
30、; 圖1 查詢(xún)編譯的階段圖</p><p> 語(yǔ)法分析與語(yǔ)法分析樹(shù)</p><p> 語(yǔ)法分析器的工作是接收用類(lèi)似SQL這樣的語(yǔ)言編寫(xiě)的文本并將之轉(zhuǎn)換成語(yǔ)法分析樹(shù),結(jié)點(diǎn)對(duì)應(yīng)于以下兩者之一:</p><p> 1)原子:它們是詞法成分,如關(guān)鍵字(如SELECT等)、關(guān)系或?qū)傩缘拿?、常?shù)、括號(hào)、操作符(如+等),以及其它成分;</p><p
31、> 2)語(yǔ)法類(lèi):即在一個(gè)查詢(xún)中起相似作用的查詢(xún)子成分所形成族的名字??梢杂眉饫ㄌ?hào)將描述性的名稱(chēng)括起來(lái)表示語(yǔ)法類(lèi)。例如,<SFW>用于表示以常用的select-from-where形式的查詢(xún),而<Condition>將用于表示屬性條件的任何表達(dá)式,如跟在SQL語(yǔ)句where之后的表達(dá)式。</p><p> 如果結(jié)點(diǎn)是一個(gè)原子,則該結(jié)點(diǎn)沒(méi)有子女。然而,若該結(jié)點(diǎn)是一個(gè)語(yǔ)法類(lèi),則其子女通
32、過(guò)該語(yǔ)言的語(yǔ)法規(guī)則之一進(jìn)行描述。</p><p> SQL的一個(gè)簡(jiǎn)單子集的語(yǔ)法</p><p> 通過(guò)給出可用于SQL子集的語(yǔ)言的某些規(guī)則,我們借此說(shuō)明語(yǔ)法分析樹(shù)的過(guò)程。</p><p><b> 1)查詢(xún)</b></p><p> 語(yǔ)法<Query>用于表示所有正則SQL查詢(xún)語(yǔ)句。它的一些語(yǔ)法規(guī)則是
33、:</p><p> <Query> ::= <SFW></p><p> <Query> ::= (<Query>)</p><p> ::=符號(hào)表示“可以表述為”。</p><p> 2)Select列表</p><p> <SelList> :
34、:= <Attribute> , <SelList></p><p> <SelList> ::= <Attribute></p><p> 這兩條規(guī)則說(shuō)明一個(gè)選擇列表可以為任何由逗號(hào)分隔的屬性列表:要么是單個(gè)屬性,要么是一個(gè)屬性、一個(gè)逗號(hào)以及一個(gè)或多個(gè)屬性的任意列表。</p><p><b> 3)F
35、rom列表</b></p><p> <FromList> ::= <Relation> , <FromList></p><p> <FromList> ::= <Relation></p><p> 這里的from列表可由任意用逗號(hào)分隔的關(guān)系列表組成。</p><p
36、> 這里只列出了部分規(guī)則,其他的規(guī)則請(qǐng)參考其他的書(shū)籍。</p><p> 我們來(lái)看這樣一個(gè)查詢(xún)語(yǔ)句:</p><p> SELECT title </p><p> FROM StarsIn</p><p> WHERE starName IN</p><p><b> (</b>
37、;</p><p> SELECT name</p><p> FROM MovieStar</p><p> WHERE birthdate LIKE ‘%1960’</p><p><b> );</b></p><p> 按照我們所描繪的語(yǔ)法,此查詢(xún)語(yǔ)句的語(yǔ)法分析樹(shù)如下所示<
38、/p><p><b> 圖2 語(yǔ)法分析樹(shù)</b></p><p> 根是語(yǔ)法類(lèi)<Query>,任何一個(gè)查詢(xún)語(yǔ)句的語(yǔ)法樹(shù)都必然是這種情況。順著數(shù)往下走,我們可知該查詢(xún)語(yǔ)句是select-from-where的形式;選擇列表僅由屬性title構(gòu)成,from列表只有一個(gè)關(guān)系StarsIn。</p><p><b> MyDB的
39、實(shí)現(xiàn)</b></p><p><b> 記錄的定義</b></p><p> 在這里,段是解析用戶(hù)命令的最小單位,若干段的集合就構(gòu)成了一條記錄。因此段和記錄的定義是進(jìn)行命令解析器及數(shù)據(jù)存儲(chǔ)的基礎(chǔ)。</p><p> 在MyDB中,段與記錄的關(guān)系可表示如下:</p><p> 圖3 段與記錄的關(guān)系<
40、;/p><p> 段和記錄的定義在hrecord.h中實(shí)現(xiàn):</p><p><b> 段的定義:</b></p><p> typedef struct FldInforStruct</p><p><b> {</b></p><p><b> /* 字段
41、名 */</b></p><p> char fldname[10] ;</p><p> /* 字段類(lèi)型 */</p><p> char fldclass[6] ;</p><p> /* 字段長(zhǎng)度 */</p><p> int fldlen ;</p><p&
42、gt; /* 小數(shù)長(zhǎng)度 */</p><p> int dicimllen ;</p><p> } FieldInfor_T ;</p><p><b> 記錄的定義:</b></p><p> typedef struct WorkAreaStruct </p><p><
43、;b> {</b></p><p> /* 記錄長(zhǎng)度 */</p><p> int reclen ;</p><p> /* 字段數(shù) */</p><p> int fldnum ;</p><p> /* 記錄總數(shù) */</p><p>
44、int rectotal ;</p><p> /* 字段結(jié)構(gòu)信息指針數(shù)組,0號(hào)單元未用 */</p><p> FieldInfor_T fldinforptr[MAX_FIELD_NUM + 1];</p><p> /* 文件指針 */</p><p> FILE *DBFile_ptr ;</p>
45、<p> } RecordWorkArea ;</p><p><b> 命令解析模塊</b></p><p> SQL語(yǔ)言是一種面向集合的結(jié)構(gòu)化查詢(xún)語(yǔ)言。用SQL語(yǔ)言編寫(xiě)的命令一般都是解釋執(zhí)行的。所謂解釋執(zhí)行,就是解釋和執(zhí)行同步,不是像編譯那樣先把程序全部掃描一遍翻譯成機(jī)器指令再直接運(yùn)行機(jī)器指令。一般SQL語(yǔ)言可以嵌套在C等其他的高級(jí)語(yǔ)言中。因此
46、,現(xiàn)在的商業(yè)用數(shù)據(jù)庫(kù)都有自己的一套編譯器系統(tǒng),實(shí)現(xiàn)SQL解釋?zhuān)ɑ蚓幾g)和高級(jí)語(yǔ)言編譯器的無(wú)縫集成。由于MyDB的各個(gè)模塊接口是采用C語(yǔ)言函數(shù)調(diào)用,因此SQL語(yǔ)言也不可避免地要和底層模塊的接口函數(shù)打交道。MyDB命令解析器具體的原理圖如下:</p><p> 圖4 命令解析器具體工作流程原理圖</p><p><b> 詞法分析器</b></p>&l
47、t;p> 詞法分析器將SQL源程序解釋成一個(gè)個(gè)獨(dú)立的記號(hào),然后將記號(hào)的類(lèi)型以及記號(hào)所對(duì)應(yīng)的值返回給語(yǔ)法分析器。</p><p> MyDB的詞法分析過(guò)程如圖所示:</p><p><b> 圖5 詞法分析</b></p><p> 首先刪除用戶(hù)命令中的空格、制表符、逗號(hào)等,提取相關(guān)的字符,這個(gè)功能由函數(shù)CutBlankTab_He
48、ad_Tail完成;</p><p> 然后掃描提取的字符串,分步將關(guān)鍵字提取出。第一步,連分隔符(如括號(hào)等)一起提取,這個(gè)由函數(shù)GetSubstr_Delimitor完成;第二步,提取分隔符內(nèi)的字符串,這步由函數(shù)GetSubstr_BetweenDelim完成;第三步,提取合法字符集,這一步由函數(shù)GetSubstr_ValidChar完成;</p><p> 將字段信息存入數(shù)組,包括
49、所提取出的字段名,字段類(lèi)型,字段長(zhǎng)度等,這個(gè)主要由函數(shù)*Change完成;</p><p> 將記錄值存入結(jié)構(gòu)中,將所提取出來(lái)的記錄值插入相應(yīng)的結(jié)構(gòu)之中。</p><p> 實(shí)現(xiàn)各流程的函數(shù)會(huì)在下面分別敘述。</p><p> MyDB的詞法分析器的關(guān)鍵字表為:</p><p> enum SysKeyWordSet</p>
50、;<p><b> {</b></p><p> CREATE,DROP,INSERT,DELETE,</p><p> SELECT,UPDATE,EXIT,HELP</p><p><b> } ;</b></p><p> 由于MyDB只是一個(gè)面向教學(xué)的微型數(shù)據(jù)庫(kù),所以
51、它所包含的關(guān)鍵字僅僅是標(biāo)準(zhǔn)SQL的一個(gè)很小的子集。</p><p> 詞法分析器的接口參數(shù):</p><p> 用戶(hù)給出的命令結(jié)構(gòu)是SQL編譯器進(jìn)行詞法分析的基礎(chǔ)。詞法分析的任務(wù)在于提取關(guān)鍵字、省略多余空格等等。所以用戶(hù)命令結(jié)構(gòu)信息的定義也是必要的。</p><p> /* 用戶(hù)命令結(jié)構(gòu)信息 */</p><p> typedef s
52、truct </p><p><b> {</b></p><p> /* 命令內(nèi)部代碼,如"INSERT" , "CREATE"等 */</p><p> SysKeyWord_Type Cmd ;</p><p> /* 表名 */</p><
53、;p> char userstr[10] ;</p><p> /* 字段信息指針 */</p><p> FieldInfor_T *fld ;</p><p> /* 記錄值指針數(shù)組 */</p><p> char *recvalptr[MAX_FIELD_NUM + 1] ;</p><p
54、> /* 查找范圍 */</p><p> char range[10] ;</p><p> /* 介詞 */</p><p> char parse[20] ;</p><p><b> /* 表達(dá)式 */</b></p><p> char expressio
55、n[30] ;</p><p> char token[100] ;</p><p> int count ;</p><p> }CmdRec_Type ;</p><p> 此接口參數(shù)定義了用戶(hù)命令的結(jié)構(gòu)信息,以便后來(lái)詞法分析中關(guān)鍵字及有效值的提取。</p><p>
56、 詞法分析器的接口函數(shù)</p><p> 詞法分析器的接口函數(shù)定義在頭文件lexical_tool.h中。主要是與詞法分析相關(guān)的函數(shù)體,包括:</p><p> void CutBlankTab_Head_Tail (char *S);</p><p> 此函數(shù)用于刪除詞頭和詞尾的空格以及控制符;</p><p> void Cut
57、Comma (char *S) ;</p><p> 此函數(shù)用于刪除詞頭逗號(hào);</p><p> int CountSymbol (char *S , char c) ;</p><p> 此函數(shù)用于計(jì)算字符個(gè)數(shù);</p><p> int GetSubstr_Delimitor (char *S , int *ScanPos , c
58、har * Delimitor , char *Substr) ;</p><p> 此函數(shù)根據(jù)分隔符集合Delimitor,在串S中掃描起點(diǎn)ScanPos,取出子串Substr,并且移動(dòng)掃描起點(diǎn)到新的位置,用于詞法分析。偽碼如下:</p><p> int GetSubstr_Delimitor(char *S , int *ScanPos , char * Delimitor ,
59、char *Substr)</p><p><b> {</b></p><p> InStr = FALSE;</p><p> /*跳過(guò)分隔符(雙引號(hào)的分隔符除外)*/</p><p> while((*ScanPos < len) && (strchr(Delimitor , *(S
60、+ (*ScanPos))) != NULL))</p><p><b> {</b></p><p> if(*(S + (*ScanPos)) == '\"')</p><p> InStr = !InStr ;</p><p> (*ScanPos) ++ ;</p>
61、<p><b> }</b></p><p> SubstrBegin = *ScanPos ;</p><p> /*掃描子串,包括雙引號(hào)內(nèi)的分隔符*/</p><p> while((*ScanPos <= len) && (InStr || (strchr (Delimitor , *(S + *
62、ScanPos)) == NULL)))</p><p><b> {</b></p><p> if(*(S + (*ScanPos)) == '\"')</p><p> InStr = !InStr ;</p><p> (*ScanPos) ++ ;</p><
63、;p><b> }</b></p><p><b> /*復(fù)制子串*/</b></p><p> strncpy(Substr , S + SubstrBegin , *ScanPos - SubstrBegin) ;</p><p><b> /*串尾加0*/</b></p>
64、;<p> (Substr + *ScanPos - SubstrBegin) = '\0' ;</p><p> ok = ((strcmp(Substr , "") != 0) && (*ScanPos) <= len) ;</p><p><b> }</b></p>&
65、lt;p> int GetSubstr_BetweenDelim(char *S , int *ScanPos , char Delim1 , char Delim2 , char *Substr);</p><p> 此函數(shù)在串S中掃描起點(diǎn),取出在分隔符Delim1和Delim2之間的子串Substr,并且移動(dòng)掃描起點(diǎn)到新的位置,用于詞法分析。偽碼如下:</p><p> i
66、nt GetSubstr_BetweenDelim(char *S , int *ScanPos , char Delim1 , char Delim2 , char *Substr)</p><p><b> {</b></p><p> left = *ScanPos ;</p><p> len = strlen(S) ;</
67、p><p> if(len == 0)</p><p><b> {</b></p><p> *Substr = '\0' ;</p><p> return (TURE) ;</p><p><b> }</b></p><p&g
68、t; /*驗(yàn)明左邊的分隔符*/</p><p> while((left < len) && (Delim1 != S[left]))</p><p><b> ++left ;</b></p><p> if(S[left] != Delim1)</p><p> return 0 ;&
69、lt;/p><p> right = left + 1 ;</p><p> /*驗(yàn)明右邊的分隔符*/</p><p> while((right < len) && S[right] != Delim2)</p><p><b> ++right ;</b></p><p&
70、gt; if(S[right] != Delim2)</p><p> return 0 ;</p><p><b> /*復(fù)制子串*/</b></p><p> strncpy(Sunstr , &S[left + 1] , right - left + 1) ;</p><p> Substr[ri
71、ght - left + 1] = '\0' ;</p><p><b> /*移動(dòng)掃描點(diǎn)*/</b></p><p> *ScanPos = right + 1 ;</p><p><b> }</b></p><p> int GetSunstr_ValidChar(ch
72、ar *S , int *ScanPos , char *ValidCh , char *Substr);</p><p> 此函數(shù)在串S中掃描起點(diǎn)后,取出由合法字符集合ValidCh組成的子串Substr,并且移動(dòng)掃描點(diǎn)到新的位置,用于詞法分析。偽碼如下:</p><p> int GetSunstr_ValidChar(char *S , int *ScanPos , char *
73、ValidCh , char *Substr)</p><p><b> {</b></p><p> len = strlen(S) ;</p><p> *Substr = '\0' ;</p><p> while((*ScanPos < len) && (strchr
74、(ValidCh , S[ScanPos])) == NULL) </p><p> ++ (*ScanPos) ;</p><p> left = *ScanPos ;</p><p> while((*ScanPos < len) && (strchr(ValidCh , S[ScanPos])) != NULL)</p>
75、<p> ++ (*ScanPos) ;</p><p><b> /*復(fù)制子串*/</b></p><p> strncpy(Substr , &S[left] , *ScanPos - left) ;</p><p> Substr[*ScanPos - left] = '\0' ;</p
76、><p> return (*ScanPos - left) ;</p><p><b> }</b></p><p> void CloseWA();</p><p> 此函數(shù)用于關(guān)閉工作區(qū)間;</p><p> void ClearCmdRec (CmdRec_Type CmdRec);
77、</p><p> 此函數(shù)用于把命令行記錄,即分析結(jié)果清0;</p><p> void CallbackCmdRec (CmdRec_Type CmdRec);</p><p> 此函數(shù)用于回收分配的指針空間并清0;</p><p> FieldInfor_T ToFldStr(char *Token , int i);</p
78、><p> 此函數(shù)通過(guò)字符串string,分別對(duì)各個(gè)參數(shù)進(jìn)行賦值;</p><p> FieldInfor_T StoreToStr(char *Token , int i);</p><p> 此函數(shù)將第i個(gè)字段信息數(shù)組Token的字段名、字段類(lèi)型,整數(shù)和小數(shù)長(zhǎng)度存入結(jié)構(gòu)中,供建表時(shí)使用;</p><p> FieldInfor_T *
79、Change(char *Token1);</p><p> 此函數(shù)用于將字段信息放入CmdRec的字段結(jié)構(gòu)數(shù)組中;</p><p> char (*Value(char *Token))[15][30];</p><p> 將用戶(hù)插入的記錄值分別存入CmdRec結(jié)構(gòu)的recvalptr中,供插入時(shí)使用;</p><p> 以上函數(shù)均
80、在lexical_too.c中進(jìn)行了實(shí)現(xiàn)。SQL命令編譯器對(duì)用戶(hù)命令進(jìn)行掃描,調(diào)用以上函數(shù)實(shí)現(xiàn)基本的詞法分析。先根據(jù)第一個(gè)字符判斷該記號(hào)可能是什么類(lèi)型,然后根據(jù)好的規(guī)則繼續(xù)分析,直到遇到一個(gè)新的記號(hào)類(lèi)型。</p><p><b> 語(yǔ)法分析器</b></p><p> 語(yǔ)法分析器依據(jù)SQL語(yǔ)言的相關(guān)規(guī)則,對(duì)由詞法分析器返回的記號(hào)序列進(jìn)行分析。語(yǔ)法分析器和詞法分析類(lèi)
81、似,不過(guò)語(yǔ)法分析器是在詞法分析的基礎(chǔ)上,對(duì)一系列記號(hào)進(jìn)行分析。</p><p> MyDB的語(yǔ)法分析過(guò)程圖如下:</p><p><b> 圖6 語(yǔ)法分析</b></p><p><b> 語(yǔ)法分析過(guò)程如下:</b></p><p> 刪除用戶(hù)命令中的詞頭尾的空格、制表符等無(wú)關(guān)元素;<
82、/p><p> 掃描用戶(hù)命令,判斷其詞性并做相應(yīng)的處理,直到掃描到用戶(hù)命令的結(jié)尾;</p><p> 實(shí)現(xiàn)語(yǔ)法分析器相應(yīng)的函數(shù)體CmdRec_Type CmdLine_To_CmdRec (char *CmdLine)的偽碼表示為:</p><p> CmdRec_Type CmdLine_To_CmdRec (char *CmdLine)</p>
83、<p><b> {</b></p><p> /*刪除命令行頭尾空格及制表符,并取得括號(hào)之間的字符串;*/</p><p> CutBlankTab_Head_Tail(CmdLine) ;</p><p> GetSubstr_BetweenDelim (CmdLine , &TokenPos , '(
84、39; , ')' , CmdRec.token) ;</p><p> while(strlen(CmdLine) >= 1)</p><p><b> {</b></p><p> for(i = 0 ; i < strlen(Cmdline) ; i ++)</p><p><
85、;b> {</b></p><p> if(判斷是否為行為動(dòng)詞)</p><p> /*存儲(chǔ)此關(guān)鍵字*/</p><p> CmdRec.Cmd = SysKeyWordArray[i].SysW_N ;</p><p> else if(判斷是否為介詞)</p><p><b>
86、 /*存儲(chǔ)此介詞*/</b></p><p> strcpy(CmdRec.parse , Token) ;</p><p> else if(判斷是否為表達(dá)式)</p><p> ptr = strchr(Token , '=') ;</p><p><b> if (ptr)</b&g
87、t;</p><p><b> {</b></p><p> strcpy(CmdRec.expression , Token) ;</p><p><b> }</b></p><p><b> else</b></p><p><b&g
88、t; {</b></p><p> /*判斷是否為全部范圍*/</p><p> ptr = strchr(Token , '*') ;</p><p><b> if(ptr)</b></p><p><b> {</b></p><p&g
89、t; strcpy(CmdRec.range , '*') ;</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><p> ptr = strchr(Token , '
90、;,') ;</p><p><b> if(ptr)</b></p><p><b> {</b></p><p> strcpy(CmdRec.range , Token) ;</p><p><b> }</b></p><p>&
91、lt;b> else</b></p><p><b> {</b></p><p> strcpy(CmdRec.userstr , Token) ;</p><p><b> }</b></p><p><b> }</b></p>
92、<p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> return ;</b></p><p><b> }</b></p>
93、<p> 對(duì)具體SQL語(yǔ)句的語(yǔ)法的判斷在Mydb.c中進(jìn)行處理。相應(yīng)的偽碼表示如下:</p><p> int main(void)</p><p><b> {</b></p><p> swich(CmdRec.Cmd)</p><p><b> {</b></p&
94、gt;<p> case CREATE:Do_Create(CmdRec) ;break</p><p> case DROP:Do_Remove(CmdRec.userstr) ;break;</p><p> case INSERT:Do_Insert(CmdRec) ;break;</p><p> case SELECT:Do
95、_Select(CmdRec,CmdRec.token) ;break;</p><p> case UPDATE:Do_Update(CmdRec,CmdRec.token);break;</p><p> case DELETE:Do_Delete(CmdRec,CmdRec.token);break;</p><p> case EXIT:exi
96、t(0);break;</p><p> case HELP:Do_Help;break;</p><p> default:break;</p><p><b> }</b></p><p><b> return 0;</b></p><p><b&
97、gt; }</b></p><p><b> SQL語(yǔ)句的實(shí)現(xiàn)</b></p><p> MyDB所支持的SQL語(yǔ)句大體遵從標(biāo)準(zhǔn)的SQL語(yǔ)句的規(guī)范。在其規(guī)范上有稍許變動(dòng)。MyDB支持標(biāo)準(zhǔn)SQL語(yǔ)句的一個(gè)子集,具體所支持的SQL語(yǔ)句的行為動(dòng)詞是:create、select、drop、delete、update、insert等。</p>&
98、lt;p> SQL語(yǔ)句的接口函數(shù)均包含在mysql.h頭文件中,在mysql.c中進(jìn)行具體的實(shí)現(xiàn)。接口函數(shù)如下:</p><p> int Do_Remove(char *file) ;</p><p> 刪除文件,相當(dāng)于Drop語(yǔ)句;</p><p> void Do_Insert(CmdRec_Type CmdRec) ;</p>&
99、lt;p> 插入語(yǔ)句,將要插入的值放入表內(nèi),插入語(yǔ)句的實(shí)現(xiàn)過(guò)程如下圖:</p><p> 圖7 Insert語(yǔ)句實(shí)現(xiàn)過(guò)程</p><p><b> 偽碼實(shí)現(xiàn)如下:</b></p><p> void Do_Insert(CmdRec_Type CmdRec)</p><p><b> {<
100、/b></p><p><b> 定位頭文件;</b></p><p><b> 讀取一級(jí)數(shù)據(jù)元;</b></p><p> 讀取二級(jí)數(shù)據(jù)元,即各字段信息;</p><p> for(i = 0 ; i < 插入字段數(shù) ; i ++)</p><p>&l
101、t;b> {</b></p><p> /*根據(jù)不同情況將要出入的記錄值寫(xiě)入文件;*/</p><p> if(插入的屬性值為float)</p><p> 將此float類(lèi)型字段值插入表中;</p><p> else if(插入的屬性值為int)</p><p> 將此int類(lèi)型字段值
102、插入表中;</p><p> else (插入的屬性值為char)</p><p> 將此char類(lèi)型字段值插入表中;</p><p><b> }</b></p><p> 每插入一條記錄,記錄總數(shù)加1;</p><p><b> 關(guān)閉數(shù)據(jù)文件;</b></
103、p><p><b> }</b></p><p> void Do_Select (CmdRec_Type CmdRec , char *Token);</p><p> 查詢(xún)語(yǔ)句,根據(jù)不同的情況實(shí)現(xiàn)對(duì)數(shù)據(jù)的簡(jiǎn)單查詢(xún),SELECT函數(shù)的分析過(guò)程如下圖:</p><p> 圖8 Select語(yǔ)句實(shí)現(xiàn)過(guò)程</p&g
104、t;<p><b> 偽碼如下:</b></p><p> void Do_Select(CmdRec_Type CmdRec , char *Token)</p><p><b> {</b></p><p> 取得運(yùn)算符在查詢(xún)條件數(shù)組中的位置;</p><p> 把數(shù)據(jù)文
105、件一二級(jí)原數(shù)據(jù)載入工作區(qū);</p><p> 取得查詢(xún)條件中字段相對(duì)應(yīng)的本記錄首位置的長(zhǎng)度以便定位;</p><p> for(m = 0 ; m < reordtotal ; m ++)</p><p><b> {</b></p><p> 逐一從文件讀取每一條記錄;</p><p&
106、gt; 根據(jù)字段類(lèi)型讀取記錄值;</p><p><b> swich(ch)</b></p><p><b> {</b></p><p> /**根據(jù)記錄類(lèi)型對(duì)取出的記錄值進(jìn)行處理即滿(mǎn)足條件的記錄輸出到屏幕**/</p><p><b> case 整形:</b>
107、</p><p> 該整型數(shù)據(jù)滿(mǎn)足條件,定位文件至該記錄頭位置;</p><p> 逐一輸出該記錄字段值;</p><p><b> break;</b></p><p><b> case 浮點(diǎn)形:</b></p><p> 該浮點(diǎn)型數(shù)據(jù)滿(mǎn)足條件,定位文件至該記錄
108、頭位置;</p><p> 逐一輸出該記錄字段值;</p><p><b> break;</b></p><p><b> case 字符型:</b></p><p> 該字符型數(shù)據(jù)滿(mǎn)足條件,定位文件至該記錄頭位置;</p><p> 逐一輸出該記錄字段值;<
109、;/p><p><b> break;</b></p><p> default:break;</p><p><b> }</b></p><p><b> }</b></p><p><b> 關(guān)閉數(shù)據(jù)文件;</b><
110、;/p><p><b> }</b></p><p> void Do_Delete(CmdRec_Type CmdRec , char *Token);</p><p> 對(duì)基本表的數(shù)據(jù)的刪除。MyDB的刪除函數(shù)的分析過(guò)程如下圖:</p><p> 圖9 Delete語(yǔ)句實(shí)現(xiàn)過(guò)程</p><p&
111、gt;<b> 偽碼如下:</b></p><p> void Do_Delete(CmdRec_Type CmdRec , char *Token)</p><p><b> {</b></p><p><b> 打開(kāi)數(shù)據(jù)文件;</b></p><p> for(m
112、 = 0 ; m < recordtotal ; m ++)</p><p><b> {</b></p><p><b> swich(ch)</b></p><p><b> {</b></p><p> /**根據(jù)刪除條件字段的類(lèi)型的不同,分流處理**/&l
113、t;/p><p><b> case 整形:</b></p><p> 滿(mǎn)足刪除條件顯示的屏幕;</p><p> 不滿(mǎn)足刪除條件的寫(xiě)入臨時(shí)新文件;</p><p><b> break;</b></p><p><b> case 浮點(diǎn)形:</b>
114、;</p><p> 滿(mǎn)足刪除條件顯示的屏幕;</p><p> 不滿(mǎn)足刪除條件的寫(xiě)入臨時(shí)新文件;</p><p><b> break;</b></p><p><b> case 字符型:</b></p><p> 滿(mǎn)足刪除條件顯示的屏幕;</p>
115、<p> 不滿(mǎn)足刪除條件的寫(xiě)入臨時(shí)新文件;</p><p><b> break;</b></p><p> default:break;</p><p><b> }</b></p><p><b> }</b></p><p>
116、<b> 關(guān)閉數(shù)據(jù)文件;</b></p><p><b> }</b></p><p> void Do_Update(CmdRec_Type CmdRec,char *Token);</p><p> 更新數(shù)據(jù)庫(kù)中的數(shù)據(jù)。MyDB中的Update函數(shù)分析過(guò)程如下圖:</p><p> 圖
117、10 Update語(yǔ)句實(shí)現(xiàn)過(guò)程</p><p><b> 偽碼如下:</b></p><p> void Do_Update(CmdRec_Type CmdRec , char *Token)</p><p><b> {</b></p><p><b> 打開(kāi)數(shù)據(jù)文件 ;<
118、/b></p><p> for(m = 0 ; m < recordtotal ; m ++)</p><p><b> {</b></p><p> /**根據(jù)字段的不同進(jìn)行分流處理**/</p><p><b> swich(ch)</b></p><p
119、><b> {</b></p><p><b> case 整形:</b></p><p> 將滿(mǎn)足更新條件的進(jìn)行更新并現(xiàn)實(shí)在屏幕;</p><p> 不滿(mǎn)足條件的寫(xiě)入臨時(shí)文件;</p><p><b> break;</b></p><p&
120、gt;<b> case 浮點(diǎn)形:</b></p><p> 將滿(mǎn)足更新條件的進(jìn)行更新并現(xiàn)實(shí)在屏幕;</p><p> 不滿(mǎn)足條件的寫(xiě)入臨時(shí)文件;</p><p><b> break;</b></p><p><b> case 字符型:</b></p>
121、<p> 將滿(mǎn)足更新條件的進(jìn)行更新并現(xiàn)實(shí)在屏幕;</p><p> 不滿(mǎn)足條件的寫(xiě)入臨時(shí)文件;</p><p><b> break;</b></p><p> default:break;</p><p><b> }</b></p><p><
122、;b> }</b></p><p><b> 關(guān)閉數(shù)據(jù)文件;</b></p><p><b> }</b></p><p> void Do_Help();</p><p> 幫助文檔,在這里就不再贅述。</p><p> void Do_Cre
123、ate(CmdRec_Type CmdRec) ;</p><p> 創(chuàng)建基本表。參見(jiàn)基本表模塊設(shè)計(jì)。</p><p><b> 基本表模塊</b></p><p> 基本表是關(guān)系數(shù)據(jù)庫(kù)的基礎(chǔ),沒(méi)有基本表提供的路徑無(wú)關(guān)的存儲(chǔ)支持,所有基于基本表的操作都將難以實(shí)現(xiàn)?;颈砟K本身就可以看做是一個(gè)表式的系統(tǒng)。</p><p
124、> 基本表模塊負(fù)責(zé)把整個(gè)數(shù)據(jù)以表的方式來(lái)管理,用戶(hù)可以通過(guò)關(guān)系名、主鍵的值以及屬性名的關(guān)聯(lián)地址唯一地操控表中的任何數(shù)據(jù)?;颈砟K在提供關(guān)聯(lián)地址支持的同時(shí),也提供基本表的其他操作。基本表的常用操作有:創(chuàng)建、刪除一個(gè)表,添加、刪除一個(gè)記錄,添加 、刪除一個(gè)列等。關(guān)于數(shù)據(jù)庫(kù)的操作本來(lái)不應(yīng)該是屬于基本表模塊的。但是數(shù)據(jù)庫(kù)由基本表組成,基本表和數(shù)據(jù)庫(kù)的關(guān)系太緊密了,如果要將數(shù)據(jù)庫(kù)的操作單獨(dú)分離成一個(gè)模塊,那它不可避免地要訪問(wèn)基本表的內(nèi)部
125、數(shù)據(jù),那樣反而造成不安全。因此,在MyDB中將數(shù)據(jù)庫(kù)的操作和基本表的操作放在一個(gè)模塊實(shí)現(xiàn)。</p><p> 在MyDB中,每一個(gè)表即對(duì)應(yīng)一個(gè)文件,表中的數(shù)據(jù)按照順序表的數(shù)據(jù)結(jié)構(gòu)進(jìn)行存儲(chǔ)、刪除、更新等等。</p><p><b> 數(shù)據(jù)組織</b></p><p> 在MyDB中,將多個(gè)表實(shí)現(xiàn)在一起,對(duì)應(yīng)一個(gè)數(shù)據(jù)庫(kù)。每個(gè)表的基本屬性信息,
126、包括表的名稱(chēng)、列的名稱(chēng)、列的數(shù)據(jù)類(lèi)型等都統(tǒng)一存放在一個(gè)二進(jìn)制文件中。將表屬性放在一個(gè)文件中的目的是為了方便查找表的信息。</p><p> MyDB的表的數(shù)據(jù)組織方式如下:</p><p> 圖11 MyDB表的組織方式圖</p><p><b> 基本表的實(shí)現(xiàn)</b></p><p> 基本表的接口函數(shù)定義在t
127、able.h頭文件中,具體實(shí)現(xiàn)是在table.c文件中。至于刪除一個(gè)表、在表中對(duì)數(shù)據(jù)進(jìn)行刪除、插入、更新等操作,在命令行解析模塊中進(jìn)行了具體的講解,這里就不再贅述。</p><p> MyDB的基本表的實(shí)現(xiàn)過(guò)程如下圖所示:</p><p> 圖12 基本表的實(shí)現(xiàn)過(guò)程</p><p><b> 打開(kāi)文件;</b></p>&l
128、t;p> 若打開(kāi)文件失敗則輸出文件不存在;若成功則計(jì)算記錄長(zhǎng)度,直到掃描所有字段結(jié)束;</p><p><b> 將數(shù)據(jù)寫(xiě)入文件;</b></p><p><b> 關(guān)閉文件指針。</b></p><p> 創(chuàng)建基本表的接口函數(shù)為:</p><p> void Do_Create (
129、CmdRec_Type CmdRec);</p><p><b> 偽碼如下:</b></p><p> void Do_Create(CmdRec_Type CmdRec)</p><p><b> {</b></p><p><b> FILE fp ;</b>&l
130、t;/p><p> int string[3] = {0,0,0} ;</p><p><b> /*打開(kāi)文件*/</b></p><p> fp = fopen(TemName , "w + b") ;</p><p> if(fp == NULL)</p><p&g
131、t;<b> {</b></p><p> printf("文件不存在\n") ;</p><p><b> }</b></p><p> for(i = 0 ; i <= CmdRec.count ; i ++)</p><p><b> {</
132、b></p><p><b> 計(jì)算記錄的長(zhǎng)度;</b></p><p><b> }</b></p><p><b> /*記錄長(zhǎng)度*/</b></p><p> string[0] = reclen ;</p><p> /*字段數(shù)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)--學(xué)生課程數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)---學(xué)生選題數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)--學(xué)生選題數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
- 高速網(wǎng)絡(luò)數(shù)據(jù)包解析器設(shè)計(jì)與FPGA實(shí)現(xiàn).pdf
- 課程設(shè)計(jì)---倉(cāng)庫(kù)管理系統(tǒng)數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)---圖的存儲(chǔ)與遍歷
- 課程設(shè)計(jì)---倉(cāng)庫(kù)管理系統(tǒng)數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)--書(shū)店管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
- 課程設(shè)計(jì)--倉(cāng)庫(kù)管理系統(tǒng)數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)---學(xué)生學(xué)籍管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)
- web開(kāi)發(fā)課程設(shè)計(jì)--數(shù)據(jù)庫(kù)實(shí)現(xiàn)設(shè)計(jì)
- 庫(kù)存數(shù)據(jù)庫(kù)設(shè)計(jì)與實(shí)現(xiàn)-職業(yè)學(xué)院課程設(shè)計(jì)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)-中小型企業(yè)工資管理的設(shè)計(jì)與實(shí)現(xiàn)
- 內(nèi)在數(shù)據(jù)庫(kù)xMMDB的SQL解析器分析與實(shí)現(xiàn).pdf
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)--圖書(shū)管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)--人力資源管理系統(tǒng)數(shù)據(jù)庫(kù)的設(shè)計(jì)與實(shí)現(xiàn)
- 內(nèi)存數(shù)據(jù)庫(kù)存儲(chǔ)管理設(shè)計(jì)與實(shí)現(xiàn).pdf
- 鍵值數(shù)據(jù)庫(kù)存儲(chǔ)引擎設(shè)計(jì)與實(shí)現(xiàn).pdf
- 《數(shù)據(jù)庫(kù)》課程設(shè)計(jì)報(bào)告--圖書(shū)借閱管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
- 數(shù)據(jù)庫(kù)課程設(shè)計(jì)圖書(shū)管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
評(píng)論
0/150
提交評(píng)論