[转贴]Delphi + MySQL 的問題探討
[转贴]Delphi + MySQL 的問題探討
前言
筆者用 Delphi 己經很久了,但由於不是全職 Programmer ,所以功力仍然很淺,慚愧。是次因為花了很多時間在 Delphi 與 MySQL 的應用上而發現很多難題,既看見不少同病相連的同道,便整理了一下所得的資料,給其他有需要的人作為參考之用。若這些資料有甚麼錯漏的地方敬請指正。
本文會以探討以 dbExpress 連結 MySQL 為主,但文未亦會提及另類的連結方法。
dbExpree 是 Borland 公司力薦的新一代跨數據庫跨平台的數據庫驅動程式架構,亦受到國內名 Delphi 作家李維先先的推薦。在設計上,該驅動程式架構的確是相當優異的。
MySQL 是最流行的發放源程式數據庫軟件,雖然它還欠缺很多大型商用數據庫的功能 (如 Stored Procedure, Trigger 等),但由於它的開發商非當著重它的速度和穩定性,所以普遍流行於網上使用,亦在商用市場中功能要求較低但要求高速高穩定的範疇內佔越來越重要的地位。由於缺少的功能都在陸續加入中,若開發商能保持既有的速度和穩定優勢,有可能更進一步佔有更多的市場比率。
從Delphi 6推出的第一個版本的dbexpress驅動程式架構未支援 MS SQL Server 己支援 MySQL 來看,這個Delphi 加 MySQL 的組合,是很有希望成為一個很好的組合的,可惜的是,在實作上,Borland 公司太過於建基於 interbase (Borland 自家產品) 作編程的藍圖,即使在開發別家數據庫的個別驅動程式時,亦常先入為主地以interbase 的方法來運作,至使產生很多不符合效率,甚至不能運作的情況。這個情況在 MySQL 的驅動程式尤其嚴重。面對這些問題,Borland 及其資助的 Team B 成員經常的第一反應是──這是MySQL本身的限制,所以不能符合這些那些功能,或導致這些那些臭蟲。但實際情況是,MySQL只是以不同(更快速直接但較少變化)的方式去達到同一目的,只是 Borland 不想花時間去適應個別數據庫的運作方法,而省時地使用了Interbase的運作模式罷了。最近 Core Lab 推出的 MySQL 驅動程式,就完全解決了近來所知的 Borland MySQL 驅動程式的絕大部份問題,還了MySQL一個清白。(注意,這不是推薦該驅動程式,因它可能也有它的問題)
最可恨的是,Borland公司自推出該驅動程式以來既不用心的修正錯誤,也不開放源程式碼讓使用者自行修正,至使無數的使用者在遇到太多不能解決的問題後均放棄了Delphi + MySQL這個組合,而2年後的今天,新使用者還是滿懷希望而來,遇到眾多不能解決的問題而浪費不少時間,最後大多失望而回。
近一個月來,在 Borland 新聞群組裡對此的投訴與要求聲音大增(筆者也是其中一個攪事份子,呵呵),亦引起不少的迴響,但未知能否加快Borland解決此問題的步伐。
版本
Delphi / Kylix
Delphi 支援 dbExpress 的有 Delphi 6 和 Delphi 7,由於使用與支援上沒甚麼分別所以不會分開探討。
Delphi 3,4,5 不能通過 dbExpress 連上 MySQL,但可通過BDE + ODBC + MyODBC 或 Zeos 或 DirectSQL 或 ADO (Delphi 5) 連上,詳見另類連接方法。
Kylix 1,2,3 基本上可使用 dbExpress ,但在 DataSnap 上有較多限制,由於筆者沒使用,所以本文甚少提及。
dbExpress Driver
現在通行的有三個版本:
dbexpmys.dll
Delphi 6 及 SP1 預設的版本,支援 MySQL 3.22.x,己過時,勿用。
dbexpmysql.dll
Delphi 6 SP2 及 Delphi 7 預設的版本,支援 MySQL 3.23.x ,為現時最通行的版本。
dbexpmy4.dll
預算支援 MySQL 4.0.x的版本,但2002年4月發表後一直沒更新,極多問題(見下 MySQL 4 獨有問題),勿用。
MySQL
現在通行的主要有:
MySQL 3.23.x (執筆時最新是3.23.55)
隱定版,大多數己開發系統正在使用的版本
MySQL 4.0.x (執筆時最新是4.0.11a)
最後測試版,應很快轉為隱定版,開發商鼓勵新開發的軟件使用這個版本,有不少增強了的功能。
MySQL 4.1.X (執筆時4.1.0可供下載源程式,安裝檔並未提供)
最新版本,有更多新增功能,最重要的是 SubQuery,由於最新版不隱定,短時間內不鼓勵使用
Libmysql.dll
這個是外界連接 MySQL 的介面驅動程式,所有版本的 dbExpress 驅動程式都經這個 dll 連上 MySQL 。基本上,每個版本的 MySQL 均有相對的 libmysql.dll。但是,由於不同版本的 libmysql.dll 的預設介面有時有一點改變,所以經常發生 libmysql.dll 與 dbexpress 驅動程式不相容的情況。簡單來說 dbexpmys.dll 要配 3.22.x 的libmysql.dll, dbexpmysql.dll 要配 3.23.x 的 dll, 而 dbexpmy4.dll 只能配 4.0.1 的 libmysql.dll (見下 MySQL 4 獨有問題)。
Borland Quality Central (品質中心)
由於下面會多次提到品質中文的文件,所以先介紹這個供使用者提議和報告臭蟲的地方。
品質中心是半官方的機制,不是由 Borland 員工直接主持而是與 Borland 有密切關係的自願人仕主持(筆:賣這麼貴連這個錢也省,唉)。在那裡發表的要求與報告,不會直接進到 Borland 的內部資料庫,而是經那些自願的系統操作員看過,測試過認為有需要才將報告傳送到 Borland 的內部資料庫處理。雖然這樣做比較轉折,但總比以前沒有機制將聲音傳到 Borland 內部好。
由於報告眾多,那些報告比較重要,那些報告較多人關註,而需要先處理的呢?品質中心提供2個機制去給系統管理員們參考。
第一個是投票,每個使用者只限5票,你可投在你認為最重要的一或數個報告中,多票數的自然比較優先的了。
第二個是評分,每個使用者都可為每份報告評分,優質的報告也偏向於得到較快的處理。
多一些使用者參與其中,不但能使資源用在更多人關註的地方,更給 Borland 更大的壓力說明我們使用者是注重我們的權利的。
參與品質中心
所有註冊使用者均可參與品質中心,即是不是註冊使用者好像也可以使用(這個我不大肯定,因我使用時己註冊了)。方法如下 :
在 http://bdn.borland.com 申請一個戶口 (任何人也可申請,不限註冊用者)
在 http://qc.borland.com/wc/wc.exe/ 登入網頁介面 或 到 http://qc.borland.com 下載Window客戶端程式。由於現時網頁介面在發中,所以功能較少和較慢。
使用你在 bdn 申請的戶口便可進人。
你可以以不同種類來溜覽,針對報告作投票(vote),評分(rate) 或提出意見(Comment)
DBExpress 官方 Driver 的問題
MySQL 4 獨有的問題
若你使用的是 MySQL 4.0.x 的版本,你會發現你根本連不上 MySQL Server。原因是你的 dbExpress 驅動程式與你的 LibMySQL.dll 版本不苻。
上文已有提及,Delphi 6/7 提供的驅動程式是針對於 MySQL 3.X 的,所以與 MySQL 4.0.x 不相符。Borland 在 2002年三月時登出了 MySQL 4.0.1 的驅動程式測試版。該驅動程式並沒加上4.0.x的新增功能,只是調整介面以配合4.0.1版的 Libmysql.dll。更可惜的是,該驅動程式測試版充滿臭蟲而且在較新版的 Libmysql.dll 中再次失效。
[dbexpmy4.dll 下載 : http://bdn.borland.com/article/0,1410,28590,00.html]
早前在網上有一個暫時解決方案,就是不用最新的 libmysql.dll,而繼續使用 4.0.1 的 libmysql.dll 來配合較新版的 MySQL Server。這方案在 4.0.9及以前的版本時確是可行的,但是在 MySQL Server 4.0.10之後的版本亦告失敗了。由於這個driver沒新增工能且臭蟲多多,即使你是使用4.0.9之前的版本,亦不建議使用這個驅動程式。
若你不想使用別家的驅動程式,現在唯一的暫時解決方案是使用 dbexpmysql.dll 配 3.23.55 (或稍早版本) 的 libmysql.dll。當然,有些MySQL4的新增工能會因此而運用不到,但大多3.23.x版本的功能還是可如常操作的,總比不能連上主機好多了。
另外的解決辦法是使用第三者提供的驅動程式,本文稍後將會稍作介紹 Core Lab 的收費驅動程式,和免費的 Open ODBC 驅動程式。最後,使用者也可選擇跳過 dbExpress 而用其他另類的連接方法,亦將於稍後討論。
你的幫助:
你可到品質中心投票評分,以加強要求更新驅動程式的聲音。
http://qc.borland.com/wc/wc.exe/details?reportid=3731
http://qc.borland.com/wc/wc.exe/details?reportid=3732
所有版本共同問題
以下問題大部份是 MySQL 驅動程式獨有的問題,但有些也是一般 dbExpress 會遇到的問題。由於問題的詳情和複制該問題的步驟均已在QC裡有詳細說明,所以我只會簡介並列出相關的QC連結。若你對某問題看不明白或不能申請QC戶口可提出,我會試試抽時間解釋詳細一些。若你發理更多的難題或你有解決方案而不想自行打在QC中,可post在這裡,我也會抽時間打進 QC 裡。
不必要的長時間 Read Lock (http://qc.borland.com/wc/wc.exe/details?reportid=3814)
若使用 TQuery / TSQLDataSet 去讀取一些較大的 Tables,dbExpress 會鎖定那些 Tables 直至移動到近尾段或關閉才解開鎖。鎖著期間所有使用者不能 insert / update / delete 那些 Tables。若某程序用這兩個組件開啟資料集後停住,或一個一個記錄慢慢的處理,就會有一大段時間所有人都不能更新那些Table,而且畫面被凍結。
解決辦法:即使用不到亦加入TClientDataSet (或直接使用 TSimpleDataSet) 並設定 PacketRecord 為 -1 令 dbexpress 一次過讀入所有資料並解鎖。這樣做可能會浪費不必要的資源,但總比所有人不能更新好。
其他連接方法:Core Lib, Open ODBC for dbexpress, BDE+ODBC, Zeos 均沒有這個問題。
多層架構不能使用 Transaction (http://qc.borland.com/wc/wc.exe/details?reportid=1074)
在多層架構(使用DataSnap)裡,若你使用Transaction去控制一個批次的更新,在任何一個Table發生錯誤時自動Roll Back,將不能成功RollBack。因為 dbExpress 會將每句SQL分成不同的 connection 去連接 mySQL,但 MySQL 不支援以不同的連接做同一個 Tranaction 的,所以Update了的將不能RollBack。
解決辦法:沒有