[碎唸] 如果讓我再來一次,我會選 PostgreSQL。

這幾年都一直混在噗浪上,超級久沒寫部落格了,好不容易有個比較長的想法,就來灌個水一下。

話說去年夏秋交際的時候換了新工作,到了現在這間小公司來寫程式,詳細的就不提了。總而言之,現在這個工作要處理的資料量比在中研院的時候還多,大概每天會有一百萬筆的新資料,每一筆都必須處理最後成為線上分析用的報表。

因為是整個打掉重練的系統,所以一開始主管打算用這幾年很夯的 NodeJS 和 MongoDB 來做。

不過後來因為遇到一些 NodeJS 效能上的問題,發現同樣邏輯的程式碼(單純地從 RabbitMQ 撈資料經過運算後存到 MongoDB 裡),在 Scala 上就算以單執行緒的方式執行,兩者的效能也差了快十倍,在 Scala 可以處理到每秒六七百筆的時候,NodeJS 只能處理到每秒六七十筆,根本不可能處理每天一百多萬筆的資料。

後來測試的結果,似乎和 NodeJS 的 Callback 效能有關,每加一層 Callback 速度就會明顯下降,但實際原因不明。但很不幸的我們的程式必須使用 Callback 的方式讓他是循序執行的,必須保證執行的順序。

雖然可能是因為我們對於 NodeJS 的掌握不夠,用錯了方法所以才會這樣,但後來為了趕上線時間,我說服了主管讓我用 Scala 來做這段。

不過這不是重點,重點是現在系統接近尾聲了,我也開始寫文件方便以後維護或交接,而在寫文件的過程中,我也開始在想如果從頭再來一次,我會選擇同樣的技術架構嗎?還是會選擇其他的方式來實做這樣的系統?

特別是在資料庫的部份,這是我第一次使用 MongoDB 資料庫來開發完整的系統,但後來我卻愈來愈覺得,如果讓我再選一次並且讓我有主導權的話,其實比起 MongoDB,我會更偏好回到 PostgresSQL 甚至是 MySQL 來開發這套系統。

對,MongoDB 的好處很多,但我發現其實對我來說這些好處有沒有似乎並沒有太大的差別,但我卻損失掉了關聯式資料庫的好處。

舉例而言,雖然大家都說 MongoDB 很快,而在某個資料量以下,他也確實也很快,但對我來說這根本沒屁用啊!

因為我要處理的資料量大到如果不先做預處理,直接用 MongoDB 做線上運算,同樣會被卡死。而當我做過預處理後,其實 MongoDB 和 PostgreSQL 的效能差距根本就沒有到數量級的差距,光是網路延遲就足夠讓使用者感受不出兩者的差異了。

至於常常被強調的 Schemaless 我更覺得是個假議題,你要寫程式怎麼可能沒有 Schema?只是看你在哪一端處理而已啊!你還是必須知道你資料庫裡的資料表叫什麼名字,資料表裡有哪些欄位,這些欄位存的資料是什麼型別(你總不可能不用驗證使用者輸入的數量是不是數字吧?),就算你不在資料庫裡定義這些 Schema,你還是必須在程式碼裡或 ORM 裡處理掉這些事啊!

更別提改 Schema 的時候了(好像開發系統必定會遇到),絕對不是說因為資料庫是 Schemaless 就只要新插的資料用新的 Schema 就好了。之前的資料要不要處理?還是要嘛!最後要嘛就是直接改資料庫把舊資料搞到符合新的 Schema,要嘛就是改程式碼讓他同時可以處理新舊 Schema 下的資料。

咿?啊這不就是在和用關聯式資料庫的時候做同樣的事嗎?

所以,在開發這套系統的時候,我根本沒享受到 MongoDB 帶給了我什麼實質的好處,但我卻失去了關聯式資料庫有的,那些方便的 SQL 語法來做資料表的結合 / Schema 的強制性所帶來的嚴謹度/Primary Key 和 Foreign Key / Transaction 帶來的資料一致性,然後還需要花費時間學習 MongoDB 的相關技術(雖然這不是壞事)而降低開發速度。

所以後來想一想,其實搞不好在這個系統上,其實回到關聯式資料庫這種一點也不夯的東西,反而會是比較合理的選擇?

回響