很多MySQL用戶都有過將Access移植到MySQL的計劃,不過這個移植過程性能和實踐的相關(guān)描述資料很少。本文將為大家總結(jié)將Access應(yīng)用程序成功移植到MySQL的要點和注意事項。
由于Access應(yīng)用程序往往是以即席(ad hoc)模式創(chuàng)建的,移植難度很大。MySQL用戶通常會遇到的兩個移植問題是:第一,數(shù)據(jù)移植問題,由于Access模式設(shè)計較差,數(shù)據(jù)質(zhì)量很低,往往會造成數(shù)據(jù)轉(zhuǎn)換過程很復(fù)雜;第二,應(yīng)用程序移植問題,Access應(yīng)用程序中的窗體和報表常包含了邏輯或設(shè)計錯誤,不可能實現(xiàn)這些文件的自動轉(zhuǎn)換。
成功的移植途徑要完成以下三個基本任務(wù):重構(gòu)模式、清洗數(shù)據(jù)和重寫應(yīng)用程序。
從Access到MySQL的移植動因
Access數(shù)據(jù)庫由于其操作簡單易用,成本較低在中小企業(yè)中的市場非常廣闊。中等技術(shù)程度的部門開發(fā)人員都會把Access作為數(shù)據(jù)庫開發(fā)的默認選擇。大家往往通過將企業(yè)數(shù)據(jù)下載到Excel里,然后將電子表格轉(zhuǎn)換成Access數(shù)據(jù)庫,然后添加即席窗體和報表來構(gòu)建Access應(yīng)用程序。由于這些程序由用戶組織構(gòu)建的,所以往往缺乏對數(shù)據(jù)形式的要求。
在Access應(yīng)用軟件移植上,MySQL用戶面臨的壓力越來越大,包括以下幾個方面:
- 數(shù)據(jù)質(zhì)量低下:Access應(yīng)用程序常常包含了過期的企業(yè)數(shù)據(jù)或來自拙劣定義模式下的損壞數(shù)據(jù);
- 安全性能低下:Access應(yīng)用程序沒有嵌入企業(yè)安全組件,不允許進行類似于基于角色的訪問控制等的高級安全設(shè)置;
- 可管理性有限:網(wǎng)絡(luò)技術(shù)無法集中管理Access應(yīng)用程序;
- 沒有基于網(wǎng)絡(luò)發(fā)布機制:Access應(yīng)用程序無法通過網(wǎng)絡(luò)進行訪問;
- 不符合SOX依從性:企業(yè)的審核程序往往會把Access應(yīng)用程序看作是一個重要的風(fēng)險來源。
數(shù)據(jù)移植問題
MySQL本身提供了一個數(shù)據(jù)移植工具—— MySQL Migration Tool。不過這個工具實際上和待轉(zhuǎn)換的數(shù)據(jù)庫的基本模式和數(shù)據(jù)一樣并不好用。而Access的模式和數(shù)據(jù)質(zhì)量問題太過深入且普遍存在,所以MySQL用戶常常會發(fā)現(xiàn)在MySQL從頭開始重建數(shù)據(jù)模式還有來得更容易些。
Access移植過程中最兩個常見的與數(shù)據(jù)質(zhì)量相關(guān)的問題是:
1. Access數(shù)據(jù)模式不是基于SQL的模式:Access開發(fā)人員往往不熟悉SQL模式設(shè)計基礎(chǔ)。MySQL的數(shù)據(jù)庫管理員會發(fā)現(xiàn),Access模式類似于Excel的電子表格,而和典型的SQL模式相去甚遠。例如,這種模式缺乏主鍵、外鍵和參照完整性約束。
2. Access數(shù)據(jù)“不干凈”:Access數(shù)據(jù)庫中往往包含很多毀壞的數(shù)據(jù),其中部分原因是由于沒有對表進行嚴(yán)格定義。有MySQL用戶曾經(jīng)發(fā)現(xiàn)在一個Access數(shù)據(jù)庫中,在本來應(yīng)該是日期字段的區(qū)域填入的卻是文本字符串。
應(yīng)用程序移植問題
成功把數(shù)據(jù)從Access接入到MySQL僅僅解決了一部分問題,還需要處理與Access應(yīng)用程序相關(guān)的窗體和報表問題。此外,你可以把多個Access應(yīng)用整合成一個web應(yīng)用;同樣的,還可以把多個Access窗體整合成一個網(wǎng)頁。雖然可以用ODBC從Access存取MySQL數(shù)據(jù),不過大多數(shù)MySQL用戶還是選擇重新編寫應(yīng)用程序。其中的原因包括:
- 質(zhì)量問題:鑒于原始的Access應(yīng)用程序不是由專業(yè)的編程人員寫的,MySQL用戶對其邏輯可行性往往持有懷疑態(tài)度。
- 想要是應(yīng)用程序適用于網(wǎng)絡(luò):大多數(shù)MySQL用戶都想把Access應(yīng)用程序轉(zhuǎn)換成動態(tài)的網(wǎng)絡(luò)架構(gòu)。
- 出于安全要求:MySQL用戶往往希望為程序加入企業(yè)級的安全特性,例如Siteminder/LDAP驗證和基于角色的訪問控制機制等。
雖然有現(xiàn)成的工具可以將Access應(yīng)用程序自動轉(zhuǎn)換成Java,不過大部分MySQL用戶發(fā)現(xiàn)自動轉(zhuǎn)換的成功率很低。一條可行的途徑是使用類似于PHP的編程語言或ActiveGrid這樣的web 2.0 visual builder來接入Access應(yīng)用程序。
MySQL快速應(yīng)用開發(fā)工具
由于將Access應(yīng)用程序移植到MySQL的過程往往需要重新構(gòu)建應(yīng)用程序,MySQL用戶能夠加速應(yīng)用程序開發(fā)過程的工具會非常感興趣。
作為Web2.0 架構(gòu)的可視化開發(fā)平臺,ActiveGrid系統(tǒng)能夠為MySQL用戶大大簡化Access應(yīng)用程序移植的任務(wù)。很多Access應(yīng)用程序開發(fā)人員(對于急于完成移植任務(wù)的MySQL數(shù)據(jù)庫管理員來說也是如此)更希望用一個可視化方式來構(gòu)建應(yīng)用程序,而對復(fù)雜的Java架構(gòu)興趣索然。對這些開發(fā)人員來說ActiveGrid應(yīng)該是個不錯的選擇。
根據(jù)模型-視圖-控制器(MVC)的三步設(shè)計模式可以助你輕松構(gòu)建一個ActiveGrid應(yīng)用程序:
1. 定義模型:模型用來定義應(yīng)用程序中的數(shù)據(jù),包括數(shù)據(jù)庫表和表之間的關(guān)系,即對象的屬性。開發(fā)者通過輸入一個現(xiàn)有數(shù)據(jù)庫模式或使用可視化數(shù)據(jù)編輯器來詳細指明這些信息。
2. 創(chuàng)建視圖:視圖用來描述應(yīng)用程序所顯示的網(wǎng)頁,是模型的外在表現(xiàn)形式。ActiveGrid能夠根據(jù)數(shù)據(jù)庫模式創(chuàng)建默認的Ajax網(wǎng)頁,此外,開發(fā)者可以用可視化屏幕生成器來創(chuàng)建全新的網(wǎng)頁。
3. 構(gòu)建控制器:控制器用來管理應(yīng)用程序內(nèi)部的各種操作,包括頁面之間的導(dǎo)航、數(shù)據(jù)的調(diào)用、安全問題和網(wǎng)絡(luò)服務(wù)。開發(fā)者可以使用可視化操作編輯器來定義新的操作,編輯器可以調(diào)用網(wǎng)絡(luò)服務(wù),也可以調(diào)用以Java或Python編寫的自定義代碼模塊。
移植Access的流程
MySQL用戶都知道Access的自動轉(zhuǎn)換工具在移植過程中往往用處不大。例如,能夠?qū)F(xiàn)有的Access應(yīng)用程序轉(zhuǎn)變?yōu)镴ava模式的工具,往往只能進行到八成,要想完成剩下的兩成任務(wù),需要花費的時間比從頭開始編寫程序還要長。
所以,移植Access的最佳方法是重新構(gòu)建模式、清洗數(shù)據(jù)、然后重寫應(yīng)用程序。雖然這樣做時間要求很緊迫,但這是唯一能保證出來的應(yīng)用程序質(zhì)量過關(guān)并能夠?qū)崿F(xiàn)日后維護的方法。
從Access到MySQL的移植過程最好能夠按照以下的步驟循序漸進的進行:
1. 重新構(gòu)建模式:在MySQL中創(chuàng)建一個新模式,要能夠反映SQL的最佳實踐,而不是簡單地在MySQL中重新創(chuàng)建Access模式。必須確保對以下的元素進行合適定義:1)主鍵;2)用于一般查詢和列連接的索引;3)外鍵,用于表數(shù)據(jù)之間的關(guān)聯(lián),以及基數(shù)約束和刪除約束傳播;4)列的缺省值;5)允許填入空值的列;6)視圖。
2. 清洗數(shù)據(jù):使用MySQL移植工具或簡單的.CSV導(dǎo)出文件從Access數(shù)據(jù)庫中抽取數(shù)據(jù),先對數(shù)據(jù)進行以下的清洗操作,然后導(dǎo)入到新的MySQL模式中:1)確保主鍵唯一性;2)確保參照完整性——檢查對所有外鍵來說有主鍵存在,保證外鍵的一一對應(yīng)關(guān)系;3)確保非空列都寫入了值;4)確保數(shù)據(jù)類型的一致,特別是日期、整數(shù)和小數(shù)數(shù)據(jù)類型;5)將清洗過的數(shù)據(jù)導(dǎo)入到新的MySQL模式中。
3. 重寫應(yīng)用程序:重新檢查一遍窗體、報表和查詢等Access應(yīng)用程序,然后利用網(wǎng)絡(luò)開發(fā)工具重新設(shè)計窗體和報表應(yīng)用程序,不要試圖轉(zhuǎn)換現(xiàn)有的應(yīng)用程序和腳本:1)將MySQL數(shù)據(jù)模式導(dǎo)入到ActiveGrid的可視化編輯工具中;2)使用網(wǎng)頁編輯器為應(yīng)用程序創(chuàng)建帶有圖形界面的新網(wǎng)頁;3)使用操作編輯器或自定義Java/Python代碼或網(wǎng)絡(luò)服務(wù)為應(yīng)用程序定義實現(xiàn)功能所必須的操作。
總結(jié)
綜上所述,很多企業(yè)為了提高安全性能和部門應(yīng)用程序的數(shù)據(jù)質(zhì)量,逐漸從Access轉(zhuǎn)向使用MySQL數(shù)據(jù)庫,將Access移植到MySQL,需要我們小心的將數(shù)據(jù)轉(zhuǎn)移到一個新的模式,并利用基于網(wǎng)絡(luò)的開發(fā)工具重新構(gòu)建應(yīng)用程序的窗體和報表。
具體移植的方法和代碼
第一步、做好數(shù)據(jù)庫的準(zhǔn)備。安裝數(shù)據(jù)源(這個就費了我好幾天了),首先點擊控制面板中的odbc數(shù)據(jù)源(32位),點擊進入后選擇用戶DSN(其實是默認的),在其中選擇MS ACCESS 97 DATABASE 這一選項,點擊其右面的配置按鈕。會出來一個窗口名字是:[Odbc microsoft 安裝]。在其中間部分選擇你所要調(diào)用的數(shù)據(jù)庫。(選擇選取按鈕)
再點擊其右側(cè)的高級選項,會彈出一個[高級設(shè)置選項]在其中設(shè)置用戶密碼和用戶名(每個名稱記好了),在欄目下方的選項類型中點擊defaultdir,在最下方的數(shù)值中輸入你的數(shù)據(jù)庫(也就是access 數(shù)據(jù)庫)。然后一個個確定回到初始位置(用戶DSN),這時候開始[添加]你剛才所加的數(shù)據(jù)源,選擇*.mdb(就是access),點擊完成。進入到另一個頁,在開頭數(shù)據(jù)源中:數(shù)據(jù)你的數(shù)據(jù)庫源名:(比如我以前使用的是taici.mdb,那么現(xiàn)在在其中輸入taici就可以了)。然后肯定要選擇你要所找的數(shù)據(jù)庫了。好了,現(xiàn)在數(shù)據(jù)庫可以告一段落了。
第二步,那就是程序倒換的問題了。
<?
$cnx = odbc_connect('taici', 'Admin', 'WSD');
記得嗎?教你輸入用戶跟密碼時候叫你記好的,就是Admin 和WSD,知道怎么做了?!
$cur= odbc_exec( $cnx, 'select * from word' );
其中的word就是其中的一個表taici
$num_row=0;
$conn=mysql_pconnect("localhost","wsd","wsd");// 連接mysql
@mysql_select_db('sms',$conn) or
die("無法連接到數(shù)據(jù)庫,請與管理員聯(lián)系!");//打開mysql的mydb數(shù)據(jù)庫
while( odbc_fetch_row( $cur )) //從sql server的mydb庫中的user表逐條取出數(shù)據(jù),如果對數(shù)據(jù)進行選擇,可在前面的select語句中加上條件判斷
{
$num_row++;
$field1 = odbc_result( $cur, 1 ); // 這里的參數(shù)i(1,2,3..)指的是記錄集中的第i個域,你可以有所選擇地進行選取,fieldi得到對應(yīng)域的值,然后你可以對fieldi進行操作
$field2 = odbc_result( $cur, 2 );
$field3 = odbc_result( $cur, 3 );
$field4 = odbc_result( $cur, 4 );
$field5 = odbc_result( $cur, 5 );
$field6 = odbc_result( $cur, 6 );
$field7 = odbc_result ($cur, 7 );
$field3 = timetoint($field3); //這里是對sql server中的datetime類型的字段進行相應(yīng)轉(zhuǎn)換處理,轉(zhuǎn)換成我所需要的int型
$querystring = "insert into tab_phrase
(phrase_content,phrase_number,phrase_inputtime,phrase_author,phrase_classid,phrase_flag,phrase_fee)
values('$field1','$field2','$field3','$field4','$field5','$field6','$field7')" ;
mysql_query($querystring,$conn);
}
function timetoint($str){
$arr1=split(" ",$str);
$datestr=$arr1[0];
//$timestr=$arr1[1];
$arr_date=split("-",$datestr);
//$arr_time=split(":",$timestr);
$year=$arr_date[0];
$month=$arr_date[1];
$day=$arr_date[2];
//$hour=$arr_time[0];
//$minute=$arr_time[1];
//$second=$arr_time[2];
$time_int=mktime($hour,$minute,$second,$month,$day,$year);
return $time_int;
}
?>
好了,寫了這么久,有問題再問好了。