摘要:MySQL資料庫作為一種網路資料庫效能十分出色,但其在應用軟體中使用較少。本文將主要探討MySQL提供的兩種資料庫介面 ——(ODBC API和C API)在VC中的應用,並且形成一個類用以封裝C API資料庫介面的功能。 關鍵詞:MySQL;資料庫介面;ODBC API;C API 下載本文配套原始碼 引言 隨著現代電腦軟硬體及網路技術的發展,在網上尋找資料已成為現在擷取資訊的最重要手段之一。眾所周知,所有的網上資訊都是儲存在網站資料庫中的,這些資訊的查詢、更新等操作的功能則是由資料庫伺服器提供的,顯然,資料庫伺服器的效能將直接關係到網站的生存。網站搭建中用的最多的資料庫伺服器是oracle和MySQL,前者功能強大,屬於旗艦型資料庫伺服器,但前期投入太大;後者功能不斷完善,簡單易用而又不失效能,並且可以免費獲得。因此,許多中小型網站的資料庫伺服器選用MySQL,而且,由於MySQL效能出色,一些大型網站也選用了MySQL。 由此可見,MySQL資料庫伺服器在網站建設中的表現是十分出色的。但是,正因為這樣,幾乎很少有人將MySQL用於應用軟體的開發中。本文將詳細介紹VC環境中MySQL資料庫伺服器不同介面的應用,並最終將產生一個CDatabase類封裝MySQL資料庫介面功能。 資料庫介面實現與應用的電腦環境:硬體,C466、128M、15G;軟體及作業系統,VISUAL C++ 6.0、MySQL 3.23.22-beta for win32、WIN98。 1 MySQL資料庫簡介 MySQL是一個真正的多使用者、多線程SQL資料庫伺服器。SQL(結構化查詢語言 (SQL))是世界上最流行的和標準化的資料庫語言,它使得儲存、更新和存取資訊更加容易。MySQL是一個客戶機/伺服器結構的實現,它由一個伺服器精靈mysqld和許多不同的客戶程式以及庫組成的。 MySQL的主要目標是快速、健壯和易用。最初是因為MySQL的創始人需要這樣的一個SQL伺服器,它能處理與任何不昂貴硬體平台上提供資料庫的廠家在一個數量級上的大型資料庫,但速度更快,MySQL因此就開發出來了。它提供C,C++,JAVA(JDBC),Perl,Python,PHP and TCL 的API介面;多平台支援,包括Solaris,SunOS,BSDI,SGI IRIX,AIX,DEC UNIX,Linux,FreeBSD,SCO OpenServer,NetBSD,OpenBSD,HPUX,Win9x and NT;多樣的資料類型,包括有/無符號1,2,3,4,8位元組integers,FLOAT,DOUBLE,CHAR,VARCHAR,TEXT,BLOB,DATE,DATETIME,YEAR,SET,ENUM;非常靈活和安全的許可權系統,密碼加密;為Windows提供ODBC介面,可通過Access與之相聯,另有第三方開發商提供多樣的 ODBC驅動程式;在MySQL 3.23中使用新MyISAM最大的表大小可達8百萬 TB(2^63個位元組);多種語言支援,但不支援中文。然而,為了實現快速、健壯和易用的目的,MySQL必須犧牲一部分靈活而強大的功能,如子查詢、預存程序與觸發器、外鍵、事物處理等。因而,MySQL在某些應用中缺乏靈活性,但這也使它對資料的處理速度較其它資料庫伺服器至少快2~3倍。 MySQL自身不支援Windows的圖形介面,因此,所有的資料庫操作及管理功能都只能在MS-DOS方式下完成。首先,必須登陸MySQL伺服器,即在提示符\MySQL\BIN>下輸入MYSQL –H host –U user –Ppassword,提示符改為mysql>時表示登陸成功。然後,選擇所操作的資料庫,即mysql> USE databasename。接著就可以用SQL語句進行查詢了。如果需要退出資料庫伺服器,可執行QUIT命令,這樣就成功退出伺服器了。當然,由於MySQL的知名度日益增加,許多第三方軟體公司推出了MySQL在Windows環境中的具有圖形介面的支援軟體,如EMS公司的EMS MYSQL MANAGER就提供了Windows形式的MySQL資料庫操作功能。 2 利用ODBC API實現MySQL資料庫功能調用 ODBC(Open Database Connectivity)即開放式資料庫互聯,作為Windows開放性結構的一個重要部分已經為很多的Windows程式員所熟悉,ODBC的工作依賴於資料庫製造商提供的驅動程式,使用ODBC API的時候,Windows的ODBC管理程式把資料庫訪問的請求傳遞給正確的驅動程式,驅動程式再使用SQL語句指示DBMS(資料庫管理系統)完成資料庫訪問工作,因此,ODBC的存在為我們開發應用程式資料庫程式提供了非常強大的能力和靈活性。在Windows下可以對多種資料庫安裝ODBC資料庫,用來串連資料庫並訪問它們的資料。 對於MySQL資料庫伺服器來說,它的製造商同樣提供了相應的ODBC驅動程式,其最新版本為myodbc-2.50.31-win95。在WIN98環境下進行安裝後,就可以利用程式設計語言通過ODBC API對MySQL資料庫進行各種ODBC所支援的操作。因為ODBC屏蔽了各種資料庫的差異,所以,原來用於對其它資料庫進行操作的程式,通過ODBC同樣能夠對MySQL資料庫進行操作。也就是說,ODBC使程式對資料庫的通用性提高了。 用VC通過ODBC API對MySQL資料庫進行編程,必須要對MySQL資料來源進行設定,具體設定1:
圖1 資料來源設定資訊 通過的設定,接著我們就可以按照一般的ODBC資料庫編程方法,對MySQL資料庫進行編程。 3 利用MySQL內建的C API函數實現資料庫功能調用 由於各個資料庫之間的差異,它們所提供的資料庫功能也就各有不同。這樣,通過ODBC API就不可能完全擁有所有的資料庫功能,因而影響了程式對資料庫的控制功能,也就不能充分發揮資料庫的能力。並且這種統一的介面還是以損失效能為前提的,這就使資料庫操作時間延長。所以,為瞭解決以上問題,MySQL的製造商在提供ODBC驅動程式的基礎上,還提供了各種編程環境下的API,其中包括C API。這些API函數很顯然能儘可能地發揮資料庫的能力,並減少資料庫操作的延長時間,但卻使程式的通用性受到嚴重影響。 MySQL提供了一套C API函數,它由一組函數以及一組用於函數的資料類型組成,這些函數與MySQL 伺服器進行通訊並訪問資料庫,可以直接操控資料庫,因而顯著地提高了操控效能。 C API資料類型包括:MYSQL(資料庫連接控制代碼)、MYSQL_RES(查詢返回結果集)、MYSQL_ROW(行集)、MYSQL_FIELD(欄位資訊)、MYSQL_FIELD_OFFSET(欄位表的位移量)、my_ulonglong(自訂的無符號整型數)等;C API提供的函數包括:mysql_close()、mysql_connect()、mysql_query()、mysql_store_result()、mysql_init()等,其中mysql_query()最為重要,能完成絕大部分的資料庫操控。 下面將具體討論資料庫操作類CDatabase通過C API的實現以及在VC中的應用。 3.1 CDatabase類的實現 CDatabase類封裝了MySQL資料庫的功能,因此不具備通用性,只能在對MySQL的應用程式中使用。下面將根據C++要求及規範給出CDatabase類的具體結構以及相關簡要介紹: class CDatabase {public: BOOL UnLockTable(); //解鎖 BOOL LockTable(char* TableName,char* PRIORITY); //加鎖 int Reload(); //重新登陸,非零時返回錯誤資訊 char* GetState(); //伺服器狀態 char* GetServerInfo(); //伺服器資訊 int GetProtocolInfo(); //協議資訊 char* GetHostInfo(); //主機資訊 char * GetClientInfo(); //客戶機資訊 char* GetFieldName(int FieldNum); //欄位名 BOOL IsEnd(); //是否最後 int DropDB(char *db); //刪除資料庫,非零時返回錯誤資訊 void SeekData(int offset); //尋找指定資料 int CreateDB(char *db); //建立資料庫,非零時返回錯誤資訊 void FreeRecord(); //釋放結果集 unsigned int GetFieldNum(); //得到欄位數 BOOL ConnectDB(Database_Param *p); //串連資料庫 MYSQL_ROW GetRecord(); //得到結果(一個記錄) my_ulonglong GetRowNum(); //得到記錄數 BOOL SelectDB(Data_Param *para); //選擇資料庫 BOOL UpdateRecord(Data_Param *para); //更新記錄 BOOL SelectRecord(Data_Param *para); //選擇記錄 BOOL InsertRecord(Data_Param *para); //插入記錄 BOOL DelRecord(Data_Param *para); //刪除記錄 BOOL SelectAll(Data_Param *para); //選擇所有記錄 char * OutErrors(); //輸出錯誤資訊 CDatabase(); //初始化資料庫 virtual ~CDatabase(); //關閉資料庫連接 private: MYSQL mysql; //資料庫連接控制代碼 MYSQL_RES *query; //結果集 MYSQL_ROW row; //記錄集 MYSQL_FIELD *field; //欄位資訊(結構體) BOOL FindSave(char *str); //尋找並儲存結果集}; 通過CDatabase類中定義的這些功能函數,我們可以通過遠程或本機完成對MySQL資料庫的絕大部分操控,並且由於定義瞭解鎖和加鎖功能,使得應用程式能夠多線程或多進程地訪問資料庫,大大提高了效能。以上函數的具體功能都是通過調用C API函數實現的。 3.2 CDatabase類在VC中的應用 第一步 建立初始化MySQL對象,並且將其初始化。即定義CDatabase類對象,這樣程式就會自動調用建構函式CDatabase(),完成初始化。 建構函式實現如下: CDatabase::CDatabase (){ mysql_init (&mysql);} 完成初始化只需定義CDatabase類對象,即 CDatabase base; 第二步 串連伺服器,並串連需要的資料庫。即調用ConnectDB(Database_Param *p)函數,結構體Database_Param中存放資料庫參數,包括主機名稱、使用者名稱、密碼、資料庫名等。該函數如返回TRUE表示串連成功,否則表示失敗。 串連函數實現如下: BOOL CDatabase::ConnectDB(Database_Param *p){if(!mysql_real_connect(&mysql,p->host,p->user,p->password,p->db,p->port,p->unix_socket,p->client_flag)){ OutErrors(); // 輸出錯誤資訊 return false;} return true;} 第三步 對資料庫進行加鎖。即調用LockTable(char* TableName,char* PRIORITY),對相應的表TableName完成相應屬性PRIORITY的加鎖,使程式相容多線程功能。 加鎖函數實現如下: BOOL CDatabase::LockTable(char* TableName,char* PRIORITY){ char str[50]; sprintf(str,"LOCK TABLES %s %s",TableName,PRIORITY); if(mysql_query(&mysql,str)) return false; return true;} 第四步 完成資料庫操作。即根據需要調用UpdateRecord(Data_Param *para)、SelectRecord(Data_Param *para)、InsertRecord(Data_Param *para)、DelRecord(Data_Param *para)等操作。其中的結構體Data_Param中存放資料庫巨集指令引數。上述兩個結構體的定義在global.h中。 InsertRecord函數實現如下,其它實現方法相似: BOOL CDatabase::InsertRecord(Data_Param *para){ char str[80]; sprintf(str,"insert into %s values(%s)",para->tab_name,para->insert_val); if(mysql_query(&mysql,str)) return false; return true;} 第五步 解鎖資料庫。即調用UnLockTable(),完成對上述被加鎖的表的解鎖。 解鎖函數實現如下: BOOL CDatabase::UnLockTable(){ if(mysql_query(&mysql,"UNLOCK TABLES")) return false; return true;} 第六步 關閉資料庫連接。即調用解構函式~CDatabase(),關閉資料庫,並自動釋放初始化時定義的CDatabase類對象。 解構函式如下: CDatabase::~CDatabase(){ if(query) mysql_free_result(query); mysql_close(&mysql);} 注意:在編譯器時,必須加入MySQL的庫檔案libmySQL.lib。 4 MySQL效能測試 4.1 ODBC API 通過索引讀取200萬行:528秒 插入35萬行: 750秒 4.2 C API 通過索引讀取200萬行:412秒 插入35萬行:435秒 4.3 其它資料庫(以MS_SQL為例,WINNT環境) 通過索引讀取200萬行:1634秒 插入35萬行:4012秒 註:以上資料是多次測量的平均值,不可避免一定的誤差,僅供參考。 5 結束語 MySQL作為一個免費的SQL資料庫,雖然功能不夠十分強大,且靈活性較差,但是,已經能夠滿足一般應用軟體的要求,而且MySQL資料庫的開發人員也在力求使之更加完善。並且,由MySQL效能測試可以看出,它對資料的處理速度明顯快於其它資料庫伺服器。因此,如果應用軟體對資料庫的效能要求較高,而同時對資料庫操作的功能及靈活性的要求不是很高的話,並且前期投入資金較少時,MySQL資料庫伺服器不失為一個最佳的選擇。 |