後端工程師的第一堂課 (20) : 現代系統資料工具 — ORM

Johnliutw
JohnLiu 的軟體工程思維
5 min readSep 25, 2022

這是篇共 30 篇的後端領域入門系列文章,預計 1 -2 週新增 1 個新文章。
在後端領域有許多資源在告訴我們怎麼寫好 Python, Golang, Java, PHP … 等各種程式語言。但卻很少告訴我們怎麼學會 Web 後端領域 的知識。

希望你可以透過這篇文章,搭配你正熟悉中的某門任何程式語言,讓你順利入門 Web 後端 :)

【後端工程師的第一堂課】全系列: https://medium.com/@johnliutw/list/da301cc31b15

什麼是 ORM

ORM,英文全名叫 Object Relational Mapping,翻譯成中文則為 物件關聯對映,相信是個較為文謅謅的講法,因此我們在實務上還是多稱為 ORM。

ORM 在網站開發的架構中,通常是在 資料庫Model (資料容器) 兩者之間,簡單來說,它是一個幫助使用者更簡便、安全的去從資料庫讀取或操作資料。

因為 ORM 的一個非常重要的特性為: 透過程式語言(PHP、Python… 等等),去操作資料庫語言( SQL )。而這也是透過物件導向的概念,產生的一種開發模式。

像是在前篇文章的例子中,有段 Notification::all() 的寫法,其實就是使用了 ORM 的技術,透過 all() 這個函式,實質上是轉換成 SELECT * FROM notifications; 這樣的 SQL 語法去執行喔!

那我們就來比較一下,使用 ORM,跟純粹使用 SQL 的優缺點吧!

ORM的優缺點

優點

  1. 安全性

首先使用 ORM 最大的優點就是在此,有一種常見的網路攻擊叫做 SQL 注入( SQL injection )。就是駭客在傳輸到網站伺服器裡的資料中,直接寫入惡意的 SQL ,讓我們網站的某段程式碼,誤讀該駭客傳來的 SQL 語法並執行。

像是假設傳來伺服器的資料有包含『 DELETE 』這種會害死大家的語句,那網站的資料就有可能會被惡意移除。

但如果是透過 ORM 的方式,就變成是操作程式語言,例如假設我們有提供使用者,可以透過 日期 來搜尋通知的功能,原本是讓使用者透過類似下述的語法:

$date = // 取得使用者傳來的日期資料
$sql = "SELECT * FROM notifications WHERE date = " + $date;
... 執行 SQL 語句

但這會有 SQL 注入的問題,因為 SQL 語句有一部份會直接用上使用者傳來的資料。但透過 ORM 可以變成像是:

$date = $_POST['date'] // 取得使用者傳來的日期資料
Notification::where('date', $date)
... 轉換成合法 SQL 語句,再執行

透過 where 函式來接收參數並包裝 SQL 語句,而 ORM 就會幫我們過濾一些奇奇怪怪,具有攻擊性的資料唷~

2. 簡化性

正如開頭的例子,假設我們每句 SQL 語法都要寫清楚,其實對於已有一定 SQL 基礎的人來說,是比較囉唆的,因此 ORM 版本主要都會簡化,時常用到的 FROM 和 SELECT 的部分,

可能讀者會想說,這又什麼好簡化的,久了不就習慣了。但筆者得說,當程式越寫越多時,會對一些重複性極高的寫法感到疲乏,而人在疲乏時就有可能犯一些愚蠢的錯誤,像是打錯字, 打翻杯子(?) 之類的…

ORM 就能較為避免此狀況發生。

3. 通用性

因為 ORM 的位置是在程式語言和資料庫之間,因此就算我們的網站未來有資料庫轉移的問題,也比較不會遇到需要改寫程式的狀況。

因為不同的資料庫間,SQL 語句的語法也會稍有差異,我們來比較下面 MySQL 和 MsSQL 做兩件同樣事:

// MySQL
SELECT * FROM TestTable WHERE id=12 LIMIT 10
// MsSQL
SELECT TOP 10 * FROM TestTable WHERE id=12

這兩個程式碼都要做同一件事,可是寫法會有所不同,因此在替換資料庫時就會需要全面檢查網站的 SQL 程式碼,或是一個 PHP 用習慣 MySQL 的工程師,換到一家使用 PHP 配 MSSQL 的公司,那SQL 部分就需要好好調整一番。

但是使用 ORM 就比較不會有這個狀況,ORM 是跟開發者對程式語言的熟悉度泛用 SQL 語法概念較有關係。

缺點

  1. 效能

這是所有 ORM 和程式工具的通病,當達成了方便性,通常都會犧牲到效能的問題,因為等於要多了 把程式語言轉譯成 SQL語言 這項工作。

不過各大程式語言的 ORM 都有持續改善,緩慢的效能大多都是 SQL 語句設計不良,而較少是因為使用 ORM 的關係。

2. 學習曲線高

對於完全初學者來說,ORM 必須融合 SQL 語言和程式語言兩個不同的概念和語法,因此學習曲線比單寫 SQL 高了一些,不過這算是針對初學者較常遇到的問題。

3. 複雜查詢維護性低

對於複雜的查詢,ORM 的使用上就較為力不從心。

我們目前遇到的都算是簡單的查詢,但如果是跨好幾個表格,且要針對部分欄位做 SUM 或者 COUNT 的工作,那就變成除了 ORM 的寫法外,還要額外寫入原生的 SQL 語法。

例如,SQL 有個詞 BETWEEN ,可以篩選某個區間的值,但是 Ruby 這個程式語言的 ORM 沒有支援,所以可能會寫成如下的語法:

User.where(“age between ? and ?”, 10, 30)

在 where 內,直接寫原生的 SQL 語句,看起來很奇怪吧XD

--

--

Johnliutw
JohnLiu 的軟體工程思維

熱愛軟體全端技術開發,較為擅長 Web 領域,並有多年線上與線下授課經驗,專精軟體新手教學。 相關合作: johnliutw@hotmail.com