指南

什麼是 ORM?應用程式如何與資料庫溝通,簡單解說

ORM(物件關聯映射器,object-relational mapper)是位於應用程式與關聯式資料庫之間的一個程式庫。開發者不必用 SQL 寫資料庫查詢,而是以程式語言中的普通物件處理資料,例如 db.booking.create(...) 或 Booking.find(...)。ORM 會把這些操作翻譯成 SQL、執行,再把結果轉回物件。常見例子有 TypeScript 的 Prisma 和 Drizzle、Python 的 SQLAlchemy,以及 C# 的 Entity Framework Core。

用 AI 做 App 時,ORM 為何重要

當 AI 應用程式生成工具為你的 App 加入資料庫時,通常也會加入一個 ORM 來連接它。你不必親手寫 ORM 程式碼,但知道它的存在會有幫助:

  • 資料模型放在程式碼裡。 ORM 的 schema 檔案往往是描述 App 資料最清楚的文件:有哪些資料表、每個資料表有哪些欄位,以及它們如何相連。閱讀它,就能快速檢查 AI 是否正確理解你的需求。
  • 資料庫的改動要經過遷移。 當你要求「在客戶資料加入電話號碼」,AI 會更新模型並建立一個遷移。明白這點,就知道為何某些改動要先套用,功能才會在正式環境生效。
  • 預設更安全。 ORM 建立查詢的方式能防範 SQL 注入攻擊,這是手動組裝查詢的 App 最常見的安全漏洞之一。
  • 效能陷阱。 ORM 很容易讓你不經意地執行數百個細小查詢,而其實一個就夠。這是 AI 生成的 App 頁面變慢的常見原因之一。

日常比喻

想像一位英國遊客和一位日本店主,兩人語言不通,要靠翻譯員溝通。

遊客(你的 App)說:「我想要你們最便宜的三款茶。」翻譯員(ORM)把它譯成準確的日文(SQL),交給店主(資料庫),再把答案譯回英文。

遊客不必學懂日文,大部分對話都沒問題。但遇上複雜的商議,直接用對方的語言溝通會更好,所以大多數 ORM 都讓開發者在有需要時直接寫原生 SQL。

ORM 如何運作

Postgres 等資料庫把資料存放在由行和列組成的資料表中,並以 SQL 查詢。程式語言則處理物件:例如一個有 date、customer 和 status 的預約。ORM 負責在兩者之間對應:

資料庫端ORM/程式碼端
資料表 bookings模型 Booking
資料列(row)一個預約物件
欄位 starts_at屬性 startsAt
外來鍵 customer_id關聯 booking.customer
SELECT、INSERT、UPDATE、DELETEfind、create、update、delete 方法

這四種操作,就是幾乎所有 App 都建基於的 CRUD 動作。

實例:用 Prisma 處理預約

以下是一個簡化的 Prisma schema,用於美容院預約 App。它描述了兩張資料表及它們的關聯:

model Customer {
  id       Int       @id @default(autoincrement())
  name     String
  email    String    @unique
  bookings Booking[]
}

model Booking {
  id         Int      @id @default(autoincrement())
  startsAt   DateTime
  service    String
  customer   Customer @relation(fields: [customerId], references: [id])
  customerId Int
}

簡單來說:一位客戶有名字、獨一無二的電郵,以及多個預約;每個預約有開始時間和服務項目,並屬於一位客戶。

現在 App 需要「Lena 即將到來的預約,由最近的排序」:

const bookings = await db.booking.findMany({
  where: {
    customer: { email: "lena@example.com" },
    startsAt: { gte: new Date() },
  },
  orderBy: { startsAt: "asc" },
});

ORM 會把它轉成大致如下的 SQL,執行後返回一串預約物件:

SELECT b.* FROM "Booking" b
JOIN "Customer" c ON c.id = b."customerId"
WHERE c.email = $1 AND b."startsAt" >= $2
ORDER BY b."startsAt" ASC;

$1 和 $2 是佔位符:電郵和日期會與查詢文字分開傳送,這正是防止 SQL 注入的做法。

遷移

如果你接著要求「讓客戶可以新增電話號碼」,AI 會在 Customer 模型中加入 phone String?(? 表示可選填),並生成一個遷移,即一段類似 ALTER TABLE "Customer" ADD COLUMN "phone" TEXT; 的小型 SQL 腳本。遷移會按次序保存,因此每個資料庫副本都可以調整至相同結構,改動紀錄也會保留。

各語言常用的 ORM

語言常用 ORM
TypeScript / JavaScriptPrisma、Drizzle、TypeORM、Sequelize
PythonSQLAlchemy、Django ORM、SQLModel
C#Entity Framework Core
JavaHibernate(常見於 Spring Data JPA)
RubyActive Record

ORM 隱藏 SQL 的程度各有不同。Prisma 使用自家的 schema 語言和查詢寫法;Drizzle 則刻意貼近 SQL 的結構,同時保持完整的型別。較輕量的工具稱為查詢建構器(query builder),例如 TypeScript 的 Knex 或 Kysely,它們協助在程式中建立 SQL,但不會把資料列映射成完整物件。

重要詞彙

詞彙意思
模型(Model)資料表及其欄位的程式碼定義。
Schema所有資料表、欄位及關聯的完整描述。
關聯(Relation)模型之間的連結,例如預約屬於某位客戶。
遷移(Migration)有版本編號、用來改變資料庫結構的腳本。
查詢建構器(Query builder)較輕量的工具,在程式中建立 SQL,但不做完整的物件映射。
N+1 問題先執行一個查詢取得列表,再為每個項目各執行一次查詢,規模一大就會變慢。
原生 SQL(Raw SQL)手寫的 SQL,在 ORM 礙事時使用。

常見誤解

  • 「ORM 就是資料庫。」 不是。它是翻譯員,你仍然需要 Postgres 之類的資料庫。
  • 「用了 ORM,就不必了解自己的資料。」 資料表設計不良,經過 ORM 一樣令人頭痛。良好的資料模型比工具更重要。
  • 「ORM 一定很慢。」 日常查詢通常沒問題。變慢多數是因為 N+1 查詢或缺少索引之類的模式,而這些都可以修正。
  • 「用了 ORM 就完全沒有 SQL 注入風險。」 標準的 ORM 方法是安全的,但如果把使用者輸入直接貼進原生 SQL,仍然危險。
  • 「修改 schema 檔案就會改動正式資料庫。」 只有在建立遷移並套用到該資料庫之後才會。

可以問你的 AI 生成工具的問題

  • 「展示資料庫 schema,並用淺白的語言解釋每張資料表及其關聯。」
  • 「這個專案用了哪個 ORM?遷移檔案放在哪裡?」
  • 「改動任何資料表之前,請先告訴我現有資料會否受影響;有數據的欄位未經我同意,絕不可刪除。」
  • 「檢查最慢的頁面有否 N+1 查詢,並在列表被篩選或排序的地方加入索引。」
  • 「確保每個使用使用者輸入的查詢都經過 ORM 或使用參數,不要用字串拼湊 SQL。」

Mythex 中的 ORM

當你的 App 需要儲存資料,Mythex 會為專案加入一個專用的 Postgres 資料庫(在聊天中提出要求,或使用 /database 指令),並把連線資料注入工作區及已發布的 App(資料庫說明)。之後,代理程式會撰寫讀取及儲存資料的程式碼。如果你有偏好,例如「用 Prisma」、「用 SQLAlchemy」或「純 SQL,不用 ORM」,請在聊天中說明。隨時可以要求它逐步講解 schema;你也可以在程式碼編輯器中閱讀檔案。如需更全面的了解,請參閱什麼是資料庫及 SQL 與 NoSQL 比較。

常見問題

簡單來說,什麼是 ORM?

ORM(物件關聯映射器,object-relational mapper)是一個程式庫,位於應用程式與關聯式資料庫之間。它讓開發者以程式語言中的普通物件讀取和儲存資料,並在背後替他們編寫 SQL 查詢。

ORM 有哪些例子?

常見的 ORM 包括 TypeScript 和 JavaScript 的 Prisma 與 Drizzle、Python 的 SQLAlchemy 及 Django ORM、C# 的 Entity Framework Core、Java 的 Hibernate,以及 Ruby on Rails 的 Active Record。

ORM 比手寫 SQL 好嗎?

視乎工作性質而定。ORM 令日常的讀寫更快寫、更安全、更易修改;而手寫 SQL 則能完全掌控複雜報表或對效能要求高的查詢。大多數 ORM 都容許你在有需要時直接改用原生 SQL。

什麼是遷移(migration)?

遷移是一段細小、有版本編號的腳本,用來改變資料庫的結構,例如新增一張資料表或一個欄位。ORM 可以根據你的資料模型生成遷移,確保每個資料庫副本(在手提電腦、測試環境及正式環境)都有相同結構。

Mythex · Pricing · 用 AI 建造任何嘢 · 網站及應用程式範本 · Mythex 比較 · AI 應用程式開發詞彙表 · 免費 AI 應用程式開發工具 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(台灣)