VPS

Prisma: ORM cho TypeScript, mạnh và yếu ở đâu

Thanh Nguyễn Đăng 9 phút đọc 4 khối lệnh

Prisma: ORM cho TypeScript, mạnh và yếu ở đâu
Mục lục bài viết
  1. Điểm mạnh thật sự
  2. Bẫy hiệu năng số một
  3. Chỗ Prisma yếu
  4. Migration trên máy chủ thật
  5. So với các lựa chọn khác
  6. Bẫy hiệu năng số một và cách phát hiện
  7. Điểm mạnh và điểm yếu, nói thẳng
  8. Chạy thay đổi cấu trúc trên máy chủ thật
  9. Câu hỏi thường gặp
  10. Bài viết liên quan

Trả lời nhanh: Prisma là lớp truy cập database cho TypeScript, nổi bật ở hai điểm: kiểu dữ liệu sinh tự động từ lược đồ nên gõ sai tên cột là báo lỗi ngay lúc viết, và quy trình migration rõ ràng. Yếu ở hai chỗ: truy vấn phức tạp phải rơi xuống viết SQL tay, và gói chạy khá nặng nên môi trường hạn chế tài nguyên sẽ thấy rõ. Bẫy hiệu năng số một là truy vấn lồng sinh ra hàng loạt lượt hỏi database.

Chọn lớp truy cập database là quyết định khó quay lui, vì nó ngấm vào mọi tầng của ứng dụng. Bài này không so sánh dàn trải mà nói rõ Prisma làm tốt cái gì, làm dở cái gì, để bạn biết mình đang đổi cái gì lấy cái gì.

Điểm mạnh thật sự

Kiểu dữ liệu tự sinh. Bạn khai báo lược đồ trong một file, chạy lệnh sinh, và toàn bộ mã truy cập database có kiểu chính xác. Đổi tên một cột mà quên sửa chỗ dùng thì trình biên dịch báo lỗi ngay, thay vì hệ thống chạy tới đó mới sập.

TerminalĐiểm mạnh thật sựbash
model SanPham {  id        Int      @id @default(autoincrement())  ten       String  gia       Decimal  @db.Decimal(12, 2)  danhMucId Int  danhMuc   DanhMuc  @relation(fields: [danhMucId], references: [id])  taoLuc    DateTime @default(now())}

Migration rõ ràng. Mỗi thay đổi lược đồ sinh ra một file SQL bạn đọc được và commit vào Git. Khi có sự cố, bạn biết chính xác thay đổi nào đã chạy trên máy chủ nào.

Dễ vào việc. Người mới đọc file lược đồ là hiểu ngay cấu trúc dữ liệu, không phải lần theo hàng chục file định nghĩa rải rác.

Bẫy hiệu năng số một

Truy vấn lồng trông rất gọn nhưng có thể sinh ra hàng loạt lượt hỏi database:

CodeBẫy hiệu năng số mộtjavascript
// Nguy hiem: moi san pham mot lan hoi danh mucconst dsSanPham = await prisma.sanPham.findMany({ take: 50 })for (const sp of dsSanPham) {  const dm = await prisma.danhMuc.findUnique({ where: { id: sp.danhMucId } })} // Dung: lay kem trong mot lanconst dsSanPham = await prisma.sanPham.findMany({  take: 50,  include: { danhMuc: true },})

Cách sai tạo ra năm mươi mốt lượt hỏi thay vì một hai lượt. Trên máy cá nhân với dữ liệu ít thì không thấy gì, lên máy thật với dữ liệu lớn thì trang chậm hẳn.

Cách phát hiện: bật ghi nhật ký truy vấn trong môi trường phát triển và đếm số dòng cho một lần tải trang. Con số tăng theo số phần tử là dấu hiệu chắc chắn. Đây cũng là bẫy giống hệt phần truy vấn lặp trong bài dọn code AI sinh, chỉ khác ngôn ngữ.

Chỗ Prisma yếu

Truy vấn phức tạp. Báo cáo tổng hợp nhiều tầng, hàm cửa sổ, truy vấn đệ quy đều vượt khả năng diễn đạt của cú pháp này. Bạn phải viết SQL tay, và khi đó mất phần kiểm tra kiểu, cũng là mất một lý do chính để chọn nó.

Kích thước và thời gian khởi động. Gói chạy khá nặng vì mang theo phần lõi biên dịch sẵn. Với máy chủ thông thường thì không sao, nhưng với môi trường giới hạn tài nguyên hoặc yêu cầu khởi động cực nhanh thì đáng cân nhắc.

Kiểm soát chi tiết truy vấn. Khi cần chỉ định chính xác cách database thực thi, bạn bị giới hạn hơn so với viết SQL trực tiếp.

Nói vậy không phải để bác bỏ: phần lớn ứng dụng có tám mươi phần trăm truy vấn đơn giản, và với phần đó Prisma rất dễ chịu. Vấn đề chỉ là bạn nên biết trước rằng hai mươi phần trăm còn lại sẽ phải viết tay.

Migration trên máy chủ thật

Đây là phần dễ gây sự cố nếu làm sai, nên nắm rõ hai lệnh:

TerminalMigration trên máy chủ thậtbash
# Tren may lam viec: sinh migration moinpx prisma migrate dev --name them-cot-trang-thai # Tren may chu that: chi ap dung migration da conpx prisma migrate deploy

Lệnh thứ nhất không bao giờ được chạy trên máy chủ thật, vì trong vài tình huống nó có thể dựng lại database. Lệnh thứ hai chỉ áp dụng những migration đã được commit, đúng thứ bạn muốn khi triển khai.

Ba việc kèm theo cho an toàn: sao lưu database trước mỗi lần chạy migration; đọc file SQL sinh ra trước khi commit vì thỉnh thoảng nó tạo ra thao tác gây khóa bảng lâu; và với bảng lớn thì tách thay đổi thành nhiều bước nhỏ để không khóa bảng quá lâu trong giờ cao điểm.

So với các lựa chọn khác

So với viết SQL trực tiếp: Prisma cho an toàn kiểu và migration có tổ chức, đổi lại thêm một lớp trừu tượng và một bước sinh mã. Dự án nhỏ với vài bảng thì viết SQL kèm một thư viện truy vấn mỏng có khi gọn hơn.

So với Drizzle: Drizzle nhẹ hơn và bám sát SQL hơn, hợp khi bạn muốn kiểm soát truy vấn. Prisma dễ vào việc hơn và có hệ sinh thái công cụ đầy đủ hơn. Bài riêng trong cụm này đi sâu vào Drizzle.

So với ORM cổ điển: Prisma không dùng mô hình đối tượng nặng, mà sinh ra hàm truy vấn có kiểu. Cách này ít phép màu hơn nên dễ đoán hơn.

Dù chọn cái nào, nhớ điều này: lớp truy cập không quyết định tốc độ, chỉ mục và thiết kế bảng mới quyết định. Khi trang chậm, hãy đọc kế hoạch thực thi theo bài đọc EXPLAIN trước khi đổ lỗi cho thư viện.

Bẫy hiệu năng số một và cách phát hiện

TerminalBẫy hiệu năng số một và cách phát hiệnbash
# Bay: lay danh sach roi lap qua tung phan tu de lay du lieu lien quan# Ket qua: mot yeu cau sinh hang tram truy van # Cach phat hien: bat ghi nhat ky truy van# Trong cau hinh: log: ['query']# Roi dem so dong log cho MOT yeu cau # Hoac do o tang co so du lieupsql -c "SELECT calls, round(mean_exec_time::numeric,1) tb_ms, left(query,70)         FROM pg_stat_statements ORDER BY calls DESC LIMIT 10;" # Truy van giong nhau lap hang tram lan la dau hieu ro nhat # Cach sua: lay du lieu lien quan trong CUNG mot truy van,# thay vi lap qua tung phan tu

Đây là bẫy mà mọi thư viện ánh xạ dữ liệu đều có, và cũng là nguyên nhân số một khiến ứng dụng chạy tốt lúc ít dữ liệu rồi chậm hẳn khi dữ liệu tăng. Kiểm nó bằng cách đếm số truy vấn, không đoán.

Điểm mạnh và điểm yếu, nói thẳng

MặtĐánh giáGhi chú
An toàn kiểu dữ liệuRất mạnhĐây là lý do chính người ta chọn
Công cụ xem và sửa dữ liệuTiệnĐỡ phải mở công cụ riêng
Quản lý thay đổi cấu trúcTốtNhưng phải rà trước khi chạy trên máy chủ thật
Truy vấn phức tạp, gộp nhóm nhiều tầngYếuPhải viết truy vấn thô, và lúc đó lợi thế mất đi
Kích thước và thời gian khởi độngNặng hơn các lựa chọn nhẹRõ nhất khi chạy trong container nhỏ

Chạy thay đổi cấu trúc trên máy chủ thật

  • Đọc tệp thay đổi cấu trúc trước khi chạy. Công cụ sinh ra nó tự động, và đôi khi nó chọn cách xóa cột rồi tạo lại, tức là mất dữ liệu.
  • Sao lưu cơ sở dữ liệu trước, và kiểm tệp sao lưu mở được.
  • Chạy trên bản sao trước, đo thời gian. Với bảng nhiều triệu dòng, một thay đổi cấu trúc có thể khóa bảng rất lâu.
  • Không dùng lệnh đồng bộ nhanh trên máy chủ thật. Lệnh đó dành cho lúc phát triển, và nó xóa dữ liệu không hỏi.

Về so sánh với các lựa chọn nhẹ hơn, xem bài so sánh mức tiêu tốn tài nguyên.

Câu hỏi thường gặp

Prisma có chậm không?

Bản thân nó không chậm đáng kể. Cái chậm là truy vấn lồng viết ngây thơ sinh ra hàng loạt lượt hỏi database. Bật ghi nhật ký truy vấn và đếm số lượt cho một lần tải trang là biết ngay mình có dính bẫy đó không.

Có dùng Prisma với database sẵn có được không?

Được, có lệnh đọc ngược cấu trúc database hiện tại thành file lược đồ. Kết quả thường cần chỉnh tay phần tên gọi và quan hệ, nhưng nó tiết kiệm rất nhiều thời gian so với khai báo lại từ đầu.

Khi nào nên viết SQL tay?

Khi cần báo cáo tổng hợp nhiều tầng, hàm cửa sổ, hoặc khi bạn phải kiểm soát chính xác cách database thực thi. Prisma cho phép chạy SQL thô, nên bạn không bị kẹt, chỉ là mất phần kiểm tra kiểu ở đoạn đó.

Chạy Prisma cần máy chủ cấu hình thế nào?

Không đòi hỏi nhiều CPU, nhưng cần đủ RAM cho tiến trình Node và database. Ổ đĩa nhanh quan trọng vì mọi truy vấn cuối cùng đều xuống đĩa, nhất là khi dữ liệu vượt quá bộ nhớ đệm.

Chia sẻ:Facebook

Thanh Nguyễn

TND

Tư vấn bản quyền, VPS và máy chủ kèm hóa đơn VAT, hợp đồng đầy đủ cho doanh nghiệp.