指南

什麼是 ORM?應用程式如何與資料庫溝通,一次看懂

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

用 AI 開發時,為什麼 ORM 很重要

當 AI 應用程式建構工具替你的應用程式加上資料庫時,通常也會順便加上一個 ORM 來和它溝通。你不必自己寫 ORM 程式碼,但知道它的存在很有幫助:

  • 你的資料模型存放在程式碼裡。 ORM 的 schema 檔通常是描述應用程式資料最清楚的文件:有哪些資料表、每個資料表有哪些欄位,以及它們之間如何連結。讀一下它,就能快速確認 AI 是否理解你的需求。
  • 資料庫的變更都透過遷移完成。 當你要求「替客戶加上電話號碼」時,AI 會更新模型並建立一份遷移檔。了解這點,就能明白為什麼有些變更要先套用到資料庫,功能才會在正式環境生效。
  • 預設就比較安全。 ORM 組合查詢的方式可以防範 SQL 注入攻擊,而手動拼接查詢正是應用程式最常見的安全漏洞之一。
  • 效能陷阱。 ORM 很容易不小心就執行上百次小查詢,而原本一次就能完成。這是 AI 開發的應用程式頁面變慢的常見原因。

日常生活的比喻

想像一位英國旅客和一位日本店家,彼此語言不通,透過翻譯溝通。

旅客(你的應用程式)說:「我想要你們最便宜的三種茶。」翻譯(ORM)把這句話精準地翻成日文(SQL),交給店家(資料庫),再把答覆翻回英文。

旅客不必學日文,大多數對話都沒問題。但遇到複雜的協商時,直接開口溝通會比較好,所以大多數 ORM 也允許開發者在需要時直接寫原生 SQL。

ORM 如何運作

像 Postgres 這類資料庫,會把資料存在由列和欄組成的資料表中,並用 SQL 查詢。程式語言則以物件來運作:例如一筆有 date、customer 和 status 的預約。ORM 負責在兩者之間對映:

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

這四種操作就是幾乎所有應用程式都建立在上面的 CRUD 動作。

實例:用 Prisma 處理預約

以下是一個簡化的 Prisma schema,描述美髮沙龍預約應用程式的兩個資料表以及它們的連結方式:

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
}

白話來說:一位客戶有姓名、不重複的電子郵件,以及多筆預約;每筆預約有開始時間、服務項目,並且屬於一位客戶。

現在應用程式想要查「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

當你的應用程式需要儲存資料時,Mythex 會為專案加上專屬的 Postgres 資料庫(在聊天中詢問,或使用 /database 指令),並把連線資訊注入工作區與已發布的應用程式(資料庫說明)。接下來由代理程式撰寫讀取和儲存資料的程式碼。如果你有偏好,例如「使用 Prisma」、「使用 SQLAlchemy」或「只用原生 SQL,不要 ORM」,直接在聊天中說明即可。隨時都可以要求它帶你瀏覽 schema;你也可以在程式碼編輯器中直接閱讀檔案。想了解更完整的架構,請參考什麼是資料庫與 SQL 與 NoSQL 的比較。

常見問題

用簡單的話說,什麼是 ORM?

ORM(物件關聯對映,object-relational mapper)是位於應用程式和關聯式資料庫之間的程式庫。開發者可以用程式語言中的一般物件來讀寫資料,而 ORM 會在背後替他們寫好 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 简体中文 繁體中文(香港)