Tại sao mình chọn Drizzle ORM thay vì Prisma cho dự án TypeScript thực tế?

Development tutorial - IT technology blog
Development tutorial - IT technology blog

Tại sao mình quyết định chia tay Prisma?

Sau hơn nửa năm đưa Drizzle ORM vào dự án SaaS thực tế, mình rút ra một bài học: Đôi khi sự tối giản mới là đỉnh cao. Trước đó, team mình cực kỳ chuộng Prisma nhờ sự tiện lợi. Tuy nhiên, khi project bắt đầu phình to, những vết nứt xuất hiện. Cold Start trên Vercel có lúc vọt lên hơn 2 giây do file binary của Prisma quá nặng. Thêm nữa, file schema.prisma dài tới 1.500 dòng khiến việc track thay đổi qua Git trở thành cơn ác mộng.

Drizzle ORM xuất hiện và giải quyết đúng những gì mình cần. Nó không tạo ra một ngôn ngữ trừu tượng mới. Thay vào đó, Drizzle bám sát cú pháp SQL thuần nhưng vẫn đảm bảo Type-safe 100%. Điểm cộng lớn nhất là nó cực kỳ nhẹ. Không binary, không overhead, tốc độ query của nó nhanh gần như tương đương với việc bạn dùng driver thuần túy.

3 trụ cột chính của Drizzle ORM

Để làm chủ công cụ này, bạn chỉ cần hiểu cách hoạt động của 3 thành phần:

  • Drizzle ORM: Thư viện lõi để viết query. Nó đóng vai trò như một query builder thông minh và linh hoạt.
  • Drizzle Kit: Công cụ CLI quản lý migration. Nó so sánh file code .ts với database hiện tại để tự động tạo file SQL.
  • Database Driver: Drizzle không trực tiếp kết nối DB. Nó tận dụng các driver có sẵn như postgres.js hoặc mysql2 để tối ưu hiệu suất.

Khác với cách tiếp cận của Prisma, Drizzle định nghĩa schema bằng chính code TypeScript. Điều này cho phép bạn tận dụng sức mạnh của biến, hàm và logic lập trình để chia nhỏ schema thành nhiều module dễ quản lý.

Hướng dẫn triển khai: Từ cài đặt đến Query đầu tiên

Dưới đây là quy trình setup PostgreSQL mình thường dùng cho các dự án thực tế. Quy trình này đã được tinh gọn để tiết kiệm thời gian nhất.

Bước 1: Khởi tạo và cài đặt

Hãy bắt đầu bằng việc cài đặt các package cần thiết. Mình chọn postgres.js vì nó có hiệu suất vượt trội hơn thư viện pg cũ.

mkdir drizzle-demo && cd drizzle-demo
npm init -y
npm install drizzle-orm postgres
npm install -D typescript drizzle-kit @types/node
npx tsc --init

Bước 2: Định nghĩa Schema bằng TypeScript

Tạo file src/db/schema.ts. Viết schema ở đây rất thích vì IDE sẽ gợi ý code ngay lập tức. Bạn không cần cài thêm plugin riêng biệt nào khác.

import { pgTable, serial, text, varchar, timestamp } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  fullName: text("full_name").notNull(),
  email: varchar("email", { length: 255 }).notNull().unique(),
  createdAt: timestamp("created_at").defaultNow(),
});

export const posts = pgTable("posts", {
  id: serial("id").primaryKey(),
  title: text("title").notNull(),
  content: text("content").notNull(),
  authorId: serial("author_id").references(() => users.id),
});

Lợi thế ở đây là tính module hóa. Bạn có thể tách mỗi bảng ra một file riêng rồi import lại, cực kỳ sạch sẽ cho các dự án có hàng chục bảng.

Bước 3: Cấu hình Migration

Tạo file drizzle.config.ts tại thư mục gốc. File này chỉ đường cho Drizzle Kit tìm thấy schema và nơi lưu trữ lịch sử thay đổi.

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  schema: "./src/db/schema.ts",
  out: "./drizzle",
  dialect: "postgresql",
  dbCredentials: {
    url: process.env.DATABASE_URL || "postgresql://user:pass@localhost:5432/db",
  },
});

Để tạo file migration, hãy chạy lệnh:

npx drizzle-kit generate

Drizzle sẽ gen ra các file SQL thuần. Bạn có thể mở ra kiểm tra và chỉnh sửa trực tiếp. Điều này minh bạch hơn nhiều so với cách Prisma quản lý ngầm.

Bước 4: Thực hiện CRUD

Thử nghiệm query đầu tiên trong file src/index.ts. Mọi thứ đều có Type-safe mà không cần chạy lệnh generate thủ công.

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import { users } from "./db/schema";
import { eq } from "drizzle-orm";

const queryClient = postgres("postgresql://user:pass@localhost:5432/db");
const db = drizzle(queryClient);

async function run() {
  // Thêm dữ liệu mới
  await db.insert(users).values({
    fullName: "Hoàng Code",
    email: "[email protected]",
  });

  // Lấy dữ liệu với đầy đủ gợi ý từ TS
  const result = await db.select().from(users);
  console.log(result);
}

run();

Bài học rút ra sau 6 tháng chạy Production

Áp dụng Drizzle giúp hiệu suất làm việc của team mình tăng đáng kể. Có 3 điểm thực tế mình muốn nhấn mạnh:

  1. Bundle size cực nhẹ: Ứng dụng của mình giảm được khoảng 15MB dung lượng khi deploy lên Lambda. Cold start giảm từ ~2s xuống còn dưới 300ms.
  2. Debug dễ dàng: Nếu query chậm, mình chỉ cần dùng hàm .toSQL(). Nó sẽ in ra câu lệnh SQL thực tế để mình mang đi tối ưu (Explain Analyze).
  3. Linh hoạt nhưng cần cẩn thận: Drizzle Kit đôi khi xử lý việc đổi tên cột (rename column) chưa thông minh bằng Prisma. Những lúc đó, mình thường sửa tay file SQL migration để đảm bảo an toàn cho dữ liệu.

Lời kết

Drizzle ORM không phải là “viên đạn bạc” thay thế hoàn toàn Prisma. Nếu bạn ưu tiên sự ổn định tuyệt đối và cộng đồng lớn, Prisma vẫn là lựa chọn tốt. Nhưng nếu bạn cần tốc độ, sự gọn nhẹ và muốn kiểm soát sâu vào SQL, hãy thử Drizzle. Hãy bắt đầu với một vài microservice nhỏ hoặc dự án cá nhân để cảm nhận sự khác biệt trước khi áp dụng đại trà.

Share: