iT邦幫忙

0

設計可跨資料庫的系統程式, 可行性如何?!

  • 分享至 

  • xImage

小弟這方面的規劃如下

  1. 不同資料庫中, 使用相同資料表
  2. 不使用資料庫的 StoredProcedure
  3. 系統的資料庫核心, 編寫各類資料庫類別的連接存取方式
  4. 每個客戶定義該系統的 資料庫類別(MySQL,Oracle, MSSQL..)
  5. 程式內的SQL語法, 皆採用標準寫法(採通用函式)
    如此設計後, 不同客戶用不同資料庫, 只需要設定好 "系統環境參數--資料庫類別", 就不需要改變程式, 即可使用.

小弟目前系統都照以上方式進行, 所缺的是還沒採用不同資料庫的客戶出現, 所以也沒實際測試.
不知大家覺得可行性如何? 請多指教!

看更多先前的討論...收起先前的討論...
總裁 iT邦好手 1 級 ‧ 2011-06-30 10:22:40 檢舉
我是都用StoredProcedure耶,只要名稱,參數定義好,前後端都可以換呀.
比較認真的回答是:
可行性是100%
但關鍵不在可行性,而是「必要性」
以及「資料庫的特長」和「跨資料庫的多選擇性」的取捨
以上因素都取決在「系統程式的性質」及「主事者的觀念」
是專案或是產品?是內部MIS系統還是軟體公司的產品?衝刺

比較隨便的回答是:
這個問題根本不存在
因為
沒有人會問「設計可跨WebServerWeb系統, 可行性如何?!」這個問題吃
我規定我們家
不准用StoredProcedure
也不准用DB Trigger忙
總裁 iT邦好手 1 級 ‧ 2011-06-30 14:04:24 檢舉
為什麼不能用SP呀??難道沒有專責的DBA負責寫嗎??
cdfu提到:
為什麼不能用SP呀??難道沒有專責的DBA負責寫嗎??


1.沒有
2.如果換資料庫,就得寫出同樣功能的SP(有寫不出來的風險)忙
總裁 iT邦好手 1 級 ‧ 2011-06-30 17:41:02 檢舉
真奇怪,台灣的軟體開發商好像很少有配專職的DBA的,可是這樣開發出來的系統,跑久了常常問題都會卡在DB...Orz
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
10
wiseguy
iT邦超人 1 級 ‧ 2011-06-30 11:21:59
最佳解答

個人以往的經驗,要做這樣跨資料庫的系統,做當然是可以做,只不過效益很不好,而且容易顧此失彼。常常為了遷就一個,就得犧牲另一個的效率。囧

先看看自己想支援幾種資料庫?MySQL、MSSQL、Oracle、DB2 ... ,想支援它們的哪個版本?你團隊裡面必須有專責的人,對每一個 RD 要用到的 SQL 在你所想要支援的資料庫中測試無誤 (想支援越多種,就耗費越多成本),並寫成資料抽象層API,讓邏輯層來叫用,以防止邏輯層自行寫了不能跨用的 SQL。這個 loading 就不輕,而且還需要精通各資料庫差異。除非公司有心想投入這個領域,要不然對一個系統軟體而言,這是個看不到的大成本。倒

你說你是用 PHP,PHP 有多種好用的資料庫抽象層可用,比如 ADODB、PEAR DB、...但它們是對 RD 端的介面統一,對 DB Server 端依然會有差異性。所以通常自己還得再包一層 DAL 層給 RD 叫用。因為敝人玩過這個,所以瞭解實在很吃力不討好,光是要 MySQL、MSSQL、Oracle 這三個要通用,就會在 select limit、timestamp format、auto_increment、...這幾個地方煩死 ...搖頭

看更多先前的回應...收起先前的回應...

wiseguy提到:
光是要 MySQL、MSSQL、Oracle 這三個要通用,就會在 select limit、timestamp format、auto_increment、...這幾個地方煩死

沒錯
所以我乾脆規定蟹堡王的伙伴們
只要是任何「只有特定資料庫才提供的功能」
什麼「select limit、timestamp format、auto_increment」
通通都不准用怒

antijava提到:
通通都不准用

連資料型態也是如此
這裡是date,那裡是datetime,還有什麼timestamp
通通不准用,一律用char(14)代替

刪到後來
只剩兩種資料型態可以用
就是文字和數字兩種哈哈

doesjudas iT邦新手 2 級 ‧ 2011-06-30 11:54:31 檢舉

timestamp不准用,一律用char(14)代替
您猜對了, 我真的這樣用!

doesjudas iT邦新手 2 級 ‧ 2011-06-30 11:55:13 檢舉

date
用 char(8) 代替.

fillano iT邦超人 1 級 ‧ 2011-06-30 12:01:07 檢舉

日期時間很麻煩,資料庫對於NULL的判斷方式都不一樣。要省事的話,用char最...

賽門 iT邦超人 1 級 ‧ 2011-06-30 13:17:20 檢舉

wiseguy提到:
煩死 ...

系統分析師: 老闆, 這個ERP系統產品開發要用什麼資料庫當後台? MS-SQL? Oracle? MySQL?.....

老闆: Oracle如何? 聽說效能很好.

系統分析師: 但好貴.

老闆: 那就MySQL吧! 不是免費?

系統分析師: 可是MySQL開發的話, 很多地方會和Oracle及MS-SQL不相容.

老闆: 那開發個跨後台的版本不就行了?!

系統分析師: 但是Oracle、MS-SQL、MySQL各有各的SQL語言特色, 要開發跨平台, 可能顧此失彼, 最後系統執行效能也不會好....

老闆: 煩死啦~~~什麼資料庫?!統統不准用.....

賽門 iT邦超人 1 級 ‧ 2011-06-30 13:32:41 檢舉

何必一定要跨平台?

只要應用程式功能符合使用者需求, 而且效能還可以, 資料庫就算只能用MySQL也是有客戶願意購買.

其實, SAP會跨到MS-SQL也是因為買了A1、B1...R3還是會建議客戶用Oracle, 既然有錢買R3, 就一定有錢買Oracle.

賽門 iT邦超人 1 級 ‧ 2011-06-30 23:39:37 檢舉

每家資料庫平台都有自己的一套最佳化的方法, 跨平台, 就必須犠牲這一塊.

所以SAP的做法不是開發一套跨平台的ERP系統, 而是AP端跨平台, DB Server端還是會為各家資料庫專門寫一堆SP, 很多核心作業還是寫在資料庫中, 像Workflow, 否則效能問題會拖垮AP.

但寫在資料庫的SP, 如果寫在MS-SQL, 會用C++ CLR, 寫在Oracle, 也是用C++, 寫在MySQL, 更是用C++, 只因C++是跨平台的程式語言, 而且, 可以用判斷平台為那一種來決定執行的程式碼段.

大型ERP系統, 很重視效能, 所以, 對大型ERP系統來講, 沒有跨平台, 而是廠商怎麼搭配, 就怎麼用的.

simon581923提到:
每家資料庫平台都有自己的一套最佳化的方法, 跨平台, 就必須犠牲這一塊.

+1000

simon581923提到:
沒有跨平台, 而是廠商怎麼搭配, 就怎麼用的.

這個真的是因廠商/產品差異而有差別

我以乙方的角度報告
我真的被問過下列問題
1.你們資料庫用Oracle?我們公司只買MS SQL,那不就要另外花錢買license?還要找會Oracle人維護?
2.你們資料庫用MS SQL?我們以前用過,後來都改用Oracle了,因為資料量大時,MS SQL效能不如Oracle
3.你們資料庫用MySQL?那種免費的資料庫,可以負擔商業應用嗎?
我大可以Google一堆文件資料
去說服客戶(但通常說服不了,IT人的偏見特強)
問題是
時間應該要花在值得的事情上
比如說:喊喊價錢打幾折、多跑幾個客戶
而不是沉迷於真理的辯證(何況根本沒有真理)

話又說回來
敝公司面對的
還不只跨「資料庫」這個問題
由於敝公司採用java solution
所以
連Application server(Tomcat,JBoss,WebSphere,WebLogic...)
或Web Server(Apache, IIS, Jetty...)
都要能「跨」
這裡的「跨」
是指「只寫一套能共用的程式,不去寫支援各種平台的程式」

期盼各位能多多體諒我們乙方的苦衷呀哭

總裁 iT邦好手 1 級 ‧ 2011-07-01 08:55:06 檢舉

SAP的作法跟我說的一樣,我規畫系統也是這樣的。

gidetw iT邦新手 4 級 ‧ 2011-07-01 14:29:39 檢舉

antijava提到:
2.你們資料庫用MS SQL?我們以前用過,後來都改用Oracle了,因為資料量大時,MS SQL效能不如Oracle

會慢嗎? M$ 不是宣傳的很好用

wiseguy iT邦超人 1 級 ‧ 2011-07-01 20:53:14 檢舉

雖然台灣的小軟體公司,通常要用什麼 solution 是被客戶牽著鼻子走,不過後來發現客戶其實也懂不到什麼皮毛,用什麼資料庫,哪知道哪種的特性如何?不過就是一句話:怕麻煩而已。尤其是學校單位與公家單位。偷笑

敝公司的系統是 LAMP 架構 (Linux + Apache + mysql + php),跟客戶不廢話,想換資料庫就先交個 50 萬開發費。通常這時客戶就會開始猶豫。然後打蛇隨棍上,告訴客戶報表都自動產生給你,完全不必你去碰 MySQL 資料庫。這時通常他就被你說服了。不需要他去管理最好了,基本上沒必要的話,根本不需要告訴客戶用啥資料庫。但是如果用需要花錢的商業版資料庫又非得告訴客戶不可,因為不可能把購買資料庫的費用自己吸收。也因為如此,所以公司本來開發 C#+ MSSQL 的 solution,不到半年就被我翻盤成 LAMP。老闆不可能會賣那種賣一套軟體,得把 2/3 的錢給微軟的傻事。除非這軟體價錢高到幾千萬那就另當別論。拍手

説到底,就是幫客戶搞定一切問題,只要讓他使用上一切OK,他才懶得管是 LAMP 還是 WISC 做的。只是對我們 RD 而言,LAMP 比較能做到 Set it and forget it. 開心

8
pantc328
iT邦高手 1 級 ‧ 2011-06-30 09:26:12

可行
我不知你用什麼系統
我用.net 的技術,然後配合如 DataAccessBlock 等等技術
只要改 Config 裡的連線字串就可以了

doesjudas iT邦新手 2 級 ‧ 2011-06-30 09:36:15 檢舉

小弟用 PHP 設計的

8
kaowoei
iT邦研究生 4 級 ‧ 2011-06-30 10:10:34

我覺得會有困難。我目前就想到兩個。
1.DB的Parameter符號不同。雖然可以用動態組SQL的方式避掉,但是就難免SQL INJECTION的問題。
2.即使是最基本的JOIN語法,同樣的下法就會有可能有不同的結果,這可能會很有問題。
因此我覺得,程式設計面做好分層,資料存取層切離後,再針對不同的資料庫做資料存取層的最佳化,這樣就不會動到太多商業邏輯與UI的部分。

看更多先前的回應...收起先前的回應...
pantc328 iT邦高手 1 級 ‧ 2011-06-30 10:22:16 檢舉

你的作法是對的

doesjudas iT邦新手 2 級 ‧ 2011-06-30 10:26:56 檢舉

DB的Parameter符號
小弟沒用過耶.

JOIN語法
這類問題, 不是可以依據 SQL-92 標準來寫, 通常應該會有支援吧, 還會出現不同結果啊 ?!

尼克 iT邦大師 1 級 ‧ 2011-06-30 10:59:24 檢舉

kaowoei提到:
即使是最基本的JOIN語法,同樣的下法就會有可能有不同的結果

不同資料庫會出現不同結果!

kaowoei提到:
即使是最基本的JOIN語法,同樣的下法就會有可能有不同的結果

nickliao1提到:
不同資料庫會出現不同結果!

在下才疏學淺,沒碰過這種 JOIN 語法
不過如果碰到這種情形
我會要求「不要用這個 JOIN 語法」
改用其他寫法謝謝

8
fillano
iT邦超人 1 級 ‧ 2011-06-30 11:08:21

關於幾個資料庫的SQL比較,可以先參考:
http://troels.arvin.dk/db/rdbms/

如果要仔細包裝以徹底解決資料庫相容性,建議你去研究一下諸如:
Doctrine
Propel
等PHP ORM方案,不用自己從頭開發。

如果真想自己來...建議:

  1. 資料庫抽象層架構在PDO上,他已經幫你處理好複雜的底層,所以你可以用一致的方法下命令。而且這部份是用C/C++寫得,速度比較快。
  2. 處理SQL語法相容性:可以考慮用類似Zend_Db_Select的方法來包裝/產生SQL語句。另外,可以考慮額外包裝好各個field與型別,例如使用xml、yaml等方式來宣告table名稱、欄位及型別、索引等。這樣可以方便資料庫遷移。另外,不管用什麼方法,記得分成兩個步驟來做查詢,先產生sql語句,再來執行查詢。用這個方法,你才有機會去修改sql以配合各資料庫的差別。
  3. 利用以上兩層class寫出你的dao class。(就看你要不要包裝到這個程度)
  4. 為了維護方便,可以考慮寫個db migration工具,來處理資料庫關聯與欄位的異動。

如果只專注在mssql/mysql,microsoft有提供mysql->mssql遷移工具,還蠻好用的。

fillano iT邦超人 1 級 ‧ 2011-06-30 11:38:39 檢舉

補充一下:
PDO文件:http://php.net/manual/en/book.pdo.php

另外,在2中,考慮到安全性,盡量是先產生sql的模板,然後給PDOStatement再來處理parameter。另外,定義好欄位的型別有一個好處,除了用escape跳脫之外,可以用php的變數型別檢查以及type casting或型別轉換函數來額外處理。

fillano iT邦超人 1 級 ‧ 2011-06-30 11:58:31 檢舉

這些做好以後,理想上的操作方式:

  1. 新增、修改、刪除資料表、調整欄位、調整關聯、調整索引:透過資料庫遷移工具來做,不直接寫sql...這樣操作方法比較一致,資料庫差別都交給程式處理
  2. 新增、查詢、修改資料,透過DAO來做。也可以考慮額外設計ActiveRecord類別啦,如果你比較喜歡這樣的操作模式。

越完整,越費工...所以還是用現成的ORM工具吧XD

6
player
iT邦大師 1 級 ‧ 2011-06-30 16:29:09
  1. 不同資料庫中, 使用相同資料表
    可以, 但是不同資料庫, 可能會有資料欄位格式無法統一的問題
    如果要跨資料庫去轉資料時, 須注意資料因轉換格式, 衍生的問題

  2. 不使用資料庫的 StoredProcedure
    這個會導致效能低下, 或是有些功能反而難做
    不同資料庫的 StoredProcedure 寫法各異

  3. 系統的資料庫核心, 編寫各類資料庫類別的連接存取方式
    這個簡單, ADO.NET, ODBC, 或PHP的PDO 都可

  4. 每個客戶定義該系統的 資料庫類別(MySQL,Oracle, MSSQL..)
    ?

  5. 程式內的SQL語法, 皆採用...(恕刪)
    ?


SQL語法比較
http://www.player.idv.tw/prog/index.php/SQL%E8%AA%9E%E6%B3%95%E6%AF%94%E8%BC%83

C#用的class SqlStringBuilder
http://www.player.idv.tw/prog/index.php/SqlStringBuilder.cs

PHP(關於PDO建議配合Zend Framework 內的 Zend Db 去使用
參見 http://framework.zend.com/

6
sheng514
iT邦新手 1 級 ‧ 2011-07-01 08:21:05

這是要看你的系統範疇多大,如果只是一般的應用系統我覺得還OK,但遇到資料量大的ERP系統,基本上要能泛用資料庫我覺得會有效能上的問題

另外有些SQL語法(比較複雜的) MS SQL 與 ORACLE 就不同
比方說日期欄位..MS SQL 可以用 StartDate = '2011-01-01',但在Oracle就要用 StartDate = to_date('2011-01-01','yyyy-mm-dd')
單就語法就很難達到所謂的共用...

不過若在資料庫邏輯層做By DB 客製化的設計,針對每種資料庫的語法進行最佳化...
我響應該還是可行... 感覺像是SQL語法翻譯器... 將程式業務邏輯層給的SQL語法搭配DB設定檔最佳化最終SQL指令.

4
ycl8000
iT邦高手 1 級 ‧ 2011-07-01 11:56:21

跨資料庫!!通吃的結果,乍看之下好像很有看頭,其實一點特色也沒有.
通才 不等於 專才
樣樣通 等於 沒一樣精
不過通才和專才孰優孰劣,沒有一定.

doesjudas iT邦新手 2 級 ‧ 2011-07-01 12:57:31 檢舉

小型設計公司的悲哀.

白天永遠不懂夜的黑抱抱

鐵殼心 iT邦高手 1 級 ‧ 2011-07-01 13:47:35 檢舉

antijava提到:
白天永遠不懂夜的黑

意思是說海綿寶寶的夜晚比白天更美麗嗎?臉紅

4
bestlong
iT邦研究生 4 級 ‧ 2011-07-02 10:59:31

技術上當然是可行
只是所增加的開發成本對公司來說,效益是否能夠接受

程式架構將存取資料庫的部分做成一層就可以切換使用不同資料庫或是不同資料庫版本

我要發表回答

立即登入回答