
概念概覽
flowchart LR C[Create 新增] -->|POST| C1[INSERT INTO] R[Read 讀取] -->|GET| R1[SELECT] U[Update 更新] -->|PUT / PATCH| U1[UPDATE] D[Delete 刪除] -->|DELETE| D1[DELETE FROM] C1 --> DB[(資料庫)] R1 --> DB U1 --> DB D1 --> DB
什麼是 CRUD?
不管你做的是社群平台、電商網站、還是一個簡單的待辦清單 App,背後都離不開四件事:新增資料、讀取資料、更新資料、刪除資料。這就是 CRUD。聽起來簡單?確實,但它就像料理的「煎煮炒炸」——所有複雜的應用,拆到最底層都是這四個動作的組合。
CRUD 是四個英文單字的縮寫,代表對資料的四種基本操作:
| 操作 | 英文 | 說明 | SQL | HTTP Method |
|---|---|---|---|---|
| 新增 | Create | 建立新資料 | INSERT | POST |
| 讀取 | Read | 查詢資料 | SELECT | GET |
| 更新 | Update | 修改資料 | UPDATE | PUT/PATCH |
| 刪除 | Delete | 移除資料 | DELETE | DELETE |
CRUD 與 RESTful API
為什麼要特別提 HTTP 方法?因為當你的前端需要跟後端溝通時,CRUD 的每一個操作都有一個「約定俗成」的 HTTP Method 與之對應。這個對應關係搞清楚了,你讀任何 API 文件都會非常順暢。
在設計 RESTful API 時,CRUD 操作直接對應到 HTTP 方法:
// 使用者資源的 CRUD API 範例
// Create - 新增使用者
POST /api/users
Body: { "name": "John", "email": "john@example.com" }
// Read - 取得所有使用者
GET /api/users
// Read - 取得單一使用者
GET /api/users/123
// Update - 更新使用者資料
PUT /api/users/123
Body: { "name": "John Doe", "email": "john.doe@example.com" }
// Delete - 刪除使用者
DELETE /api/users/123資料庫 CRUD 操作
SQL 範例
-- Create: 新增資料
INSERT INTO users (name, email, created_at)
VALUES ('John', 'john@example.com', NOW());
-- Read: 查詢資料
SELECT * FROM users WHERE id = 1;
SELECT * FROM users WHERE email LIKE '%@example.com';
-- Update: 更新資料
UPDATE users
SET name = 'John Doe', updated_at = NOW()
WHERE id = 1;
-- Delete: 刪除資料
DELETE FROM users WHERE id = 1;ORM 範例(使用 Prisma)
// Create
const user = await prisma.user.create({
data: {
name: 'John',
email: 'john@example.com',
},
});
// Read
const user = await prisma.user.findUnique({
where: { id: 1 },
});
const users = await prisma.user.findMany({
where: { email: { contains: '@example.com' } },
});
// Update
const updatedUser = await prisma.user.update({
where: { id: 1 },
data: { name: 'John Doe' },
});
// Delete
const deletedUser = await prisma.user.delete({
where: { id: 1 },
});軟刪除 vs 硬刪除
硬刪除(Hard Delete)
直接從資料庫移除資料,資料無法復原。
DELETE FROM users WHERE id = 1;軟刪除(Soft Delete)
保留資料但標記為已刪除狀態,資料可以復原。
-- 軟刪除
UPDATE users
SET deleted_at = NOW(), is_deleted = true
WHERE id = 1;
-- 查詢時排除已刪除的資料
SELECT * FROM users WHERE is_deleted = false;
-- 復原資料
UPDATE users
SET deleted_at = NULL, is_deleted = false
WHERE id = 1;在商業應用中,軟刪除通常是更好的選擇,原因包括:
- 資料可追溯和復原
- 符合法規要求(如 GDPR 的資料保留期限)
- 避免關聯資料完整性問題
CRUD 最佳實踐
1. 資料驗證
在執行 CRUD 操作前,務必驗證輸入資料。
// 使用 Zod 進行資料驗證
import { z } from 'zod';
const userSchema = z.object({
name: z.string().min(2).max(50),
email: z.string().email(),
});
// 驗證後再進行 Create
const validatedData = userSchema.parse(inputData);
await prisma.user.create({ data: validatedData });2. 權限控制
確保使用者只能操作有權限的資料。
// 確認使用者有權限更新此資源
const post = await prisma.post.findUnique({ where: { id: postId } });
if (post.authorId !== currentUser.id) {
throw new Error('Unauthorized');
}
await prisma.post.update({
where: { id: postId },
data: updateData,
});3. 交易處理
多個 CRUD 操作需要保證原子性時使用交易。
await prisma.$transaction(async (tx) => {
// 扣除帳戶餘額
await tx.account.update({
where: { id: fromAccountId },
data: { balance: { decrement: amount } },
});
// 增加目標帳戶餘額
await tx.account.update({
where: { id: toAccountId },
data: { balance: { increment: amount } },
});
});CRUD 與其他概念的關係
- CRUD 是對資料操作的描述,著重於「做什麼」
- RESTful API 是 API 設計風格,定義「如何做」
- HTTP Methods 是傳輸協定的動詞,是「怎麼傳輸」
三者是不同層面的概念,但在實務上緊密結合。