Sequelize và Prisma

Bắt đầu

Hiện tại tại eBay, tôi đang di chuyển các công cụ nội bộ của chúng tôi từ việc sử dụng MongoDB sang Postgres. Đó là một dự án rất khó nhưng tôi rất hào hứng để đối mặt trực tiếp. Trong quá trình nghiên cứu, tôi xác định rằng đối với cơ sở mã của chúng tôi, sử dụng một ORM sẽ là tốt nhất vì cơ sở mã đã được thiết kế để sử dụng Mongoose. Nhưng bây giờ thách thức là, ORM nào sẽ phù hợp nhất cho cơ sở mã của chúng tôi? Trong blog này, tôi sẽ đi sâu vào câu hỏi đó. Xin lưu ý rằng tôi không thể tiết lộ mọi thứ trong blog này do tính chất mối quan hệ của tôi với nhà tuyển dụng.

Yêu cầu

Sau khi phân tích cẩn thận các nhu cầu của dự án, tôi thiết lập các tiêu chí thiết yếu sau mà bất kỳ giải pháp ORM nào cũng cần thỏa mãn:

  • Là một gói JavaScript; vì hầu hết mã được viết bằng JavaScript
  • Phải hỗ trợ Postgres và hầu hết các tính năng của nó
  • Hiệu năng phải ít nhất tương đương hoặc tốt hơn Mongoose
  • Phải là mã nguồn mở và được duy trì

Các ORM

Sau khi nghiên cứu nhiều, tôi xác định ba ORM hàng đầu phù hợp với các yêu cầu là: Sequelize, Prisma, & TypeORM. Cuối cùng, tôi quyết định chỉ tập trung vào Sequelize và Prisma vì tôi không có thời gian để thử nghiệm đầy đủ ba ORM khác nhau do hạn chót.

Môi trường thử nghiệm

Cho môi trường thử nghiệm của mình, tôi chạy Postgres qua Docker. Tôi lấy tập dữ liệu lớn và phức tạp nhất của chúng tôi, chuyển đổi nó từ cấu trúc tài liệu sang cấu trúc bảng, và thêm nó vào instance Postgres cục bộ của tôi. Tôi chuyển đổi tập dữ liệu bằng cách sử dụng các cột, quan hệ một-một, quan hệ một-nhiều, và một vài cột JSONB.

Từ đó, tôi viết mã JavaScript sử dụng ORM cụ thể đó và đo:

  • Mất bao lâu để tạo một mục
  • Mất bao lâu để cập nhật một mục
  • Mất bao lâu để cập nhật một mục lồng nhau (quan hệ và/hoặc khóa-giá trị trong JSON)
  • Mất bao lâu để xóa một mục
  • Mất bao lâu để truy vấn/lấy một mục

Tôi tạo các kho lưu trữ cho mỗi môi trường thử nghiệm ORM. Tôi rất muốn chia sẻ các kho này nhưng về mặt kỹ thuật chúng thuộc sở hữu của eBay, nên tôi không thể chia sẻ chúng.

Kết quả

Khoảng ngày 15 tháng 05, 2023, tôi quyết định rằng Sequelize là ORM tốt hơn cho trường hợp sử dụng của chúng tôi và rằng nó sẽ là ORM được sử dụng cho việc di chuyển của chúng tôi từ MongoDB sang Postgres. Cuối cùng, tôi chọn Sequelize vì:

  • Nó là “thực sự mã nguồn mở” và không được duy trì bởi một startup có vốn đầu tư.
  • Hỗ trợ hầu hết các tính năng của Postgres.
  • Có hiệu năng tốt, đặc biệt so với Prisma.
  • Có tài liệu tốt, mặc dù không được tài liệu hóa tốt bằng tài liệu của Prisma.

Tôi quyết định dùng Sequelize, nhưng tôi cũng lập danh sách ưu và nhược điểm cho mỗi ORM tôi đã thử với hy vọng nó sẽ giúp mọi người xác định tốt hơn liệu Sequelize hay Prisma có phù hợp cho trường hợp sử dụng của bạn hay không.

Ưu & Nhược điểm của Sequelize

Ưu điểm:

  • Có hàm sync() tự động tạo và xử lý bảng cho bạn
  • Có thể xử lý các phép join phức tạp (dữ liệu lồng nhau)
  • Hỗ trợ nhiều tùy chọn lọc (chẳng hạn Regex)
  • Việc biểu diễn model/schema được thực hiện bằng JavaScript thuần sử dụng các lớp có thể tùy biến cao.
  • Sequelize quản lý kết nối cho cơ sở dữ liệu mà bạn chọn.
  • Sequelize hỗ trợ nhiều kết nối đọc
  • Hỗ trợ truy vấn SQL thuần.
  • Tính đến ngày 15 tháng 05 năm 2023:
    • Trên NPM, Sequelize được cập nhật lần cuối “14 ngày trước” và nhận 1,505,835 lượt tải xuống hàng tuần.
    • Trên GitHub, Sequelize được cập nhật lần cuối “hôm qua”, có 4.2k Forks, và 27.9k Stars.
    • Sequelize có giấy phép MIT và đã là mã nguồn mở hơn 10 năm. Vì vậy rất có khả năng nó sẽ tiếp tục là mã nguồn mở trong tương lai gần.

Nhược điểm:

  • Việc biểu diễn model/schema có thể trở nên rất phức tạp và phình to. Ví dụ, biểu diễn Mongoose của tập dữ liệu lớn của chúng tôi dài khoảng 262 dòng (bao gồm khoảng trắng). Cùng một tập dữ liệu được biểu diễn bằng Sequelize dài 564 dòng (bao gồm khoảng trắng).
  • Cú pháp cho Sequelize trở nên rất rối và phức tạp trong một số trường hợp.
  • Việc di chuyển cơ sở dữ liệu của bạn (chỉnh sửa nó) rất phiền toái. Bạn có thể sử dụng sequelize-cli để tạo mẫu script migration bằng JavaScript. NHƯNG, điều này dường như là trường hợp chung với hầu hết các ORM. Việc di chuyển trong cơ sở dữ liệu quan hệ thường không dễ dàng trong hầu hết các trường hợp.
  • Tài liệu không quá tuyệt vời. Nó đã trở nên tốt hơn nhưng vẫn cần cải thiện. Nhưng với các công cụ như ChatGPT, đây không còn là vấn đề lớn như trước vì ChatGPT có khả năng hiểu rất tốt về Sequelize, có lẽ do Sequelize tồn tại được một thập kỷ.
  • Sequelize không nhạy cảm với kiểu dữ liệu bằng Prisma, điều này có thể dẫn đến các vấn đề.
  • Nó không hỗ trợ TypeScript tốt, điều này đối với dự án của tôi không phải là vấn đề nhưng với nhiều dự án khác có thể là một vấn đề lớn.

Ưu và nhược điểm của Prisma

Ưu điểm:

  • Có ngôn ngữ schema riêng. Điều này có nghĩa là bạn có thể dễ dàng và sạch sẽ hơn khi tạo schema/model. Ví dụ, biểu diễn Mongoose của tập dữ liệu lớn của chúng tôi dài khoảng 262 dòng (bao gồm khoảng trắng). Nhưng cùng một tập dữ liệu được biểu diễn bởi Prisma chỉ dài 221 dòng (bao gồm khoảng trắng).
  • Prisma có công cụ CLI giúp dễ dàng hơn trong việc tạo và di chuyển (chỉnh sửa) cơ sở dữ liệu của bạn. Điều này rất tiện lợi. Nó không phải là thuốc chữa bách bệnh nhưng là điều tốt nhất tôi từng thấy từ một ORM cho đến nay.
  • Hỗ trợ truy vấn SQL thuần.
  • Mã cho Prisma sạch và đơn giản. Bạn vẫn phải học và làm quen với cú pháp của Prisma nhưng dễ hiểu hơn nhiều so với cú pháp của Sequelize.
  • Prisma có một client tự động sinh các trình xây dựng truy vấn cho Node.js & TypeScript.
  • Tài liệu rất rất tốt và rõ ràng. ChatGPT vẫn có thể giúp nhưng nó không cập nhật về Prisma nhanh bằng về Sequelize.
  • Tính đến ngày 15 tháng 05 năm 2023:
    • Trên NPM, Prisma được cập nhật lần cuối “6 ngày trước” và nhận 1,344,705 lượt tải xuống hàng tuần.
    • Trên GitHub, Prisma được cập nhật lần cuối “3 giờ trước”, có 1.1k Forks, và 31.3k Stars.

Nhược điểm:

  • Không hỗ trợ lọc Regex cho Postgres nhưng có các tùy chọn lọc “contains”, “includes”, và “startsWith”.
  • Từ việc thử nghiệm của tôi, Prisma chậm hơn đáng kể khi tạo các mục của tập dữ liệu lớn của chúng tôi trong Postgres. Sequelize tạo những mục lớn đó với tốc độ khoảng 2.26 giây cho mỗi mục (file JSON). Trong khi Prisma có tốc độ khoảng 11.21 giây cho mỗi mục (file JSON). Dựa trên kết quả này, Prisma chậm hơn khoảng 5 lần so với Sequelize ở tác vụ này.
  • Ngoài ra, việc xóa một mục khỏi tập dữ liệu lớn dẫn đến thời gian chờ gần 4 phút, điều này rất rất tệ.
  • Sequelize nhanh hơn nhiều khi xóa một mục trong tập dữ liệu lớn và phức tạp nhất trong các bài kiểm tra của tôi. Sequelize không có lợi thế so với Prisma khi xây dựng tập dữ liệu. Cả hai đều phải xử lý một quan hệ sâu ba lớp cho tập dữ liệu lớn này, nên tôi sẽ nói đó là một so sánh công bằng.
  • Prisma là một startup, nghĩa là Prisma là một công ty vì lợi nhuận với 56.5 triệu đô la tài trợ. Biết điều này, mã/gói ORM chính của Prisma là mã nguồn mở với giấy phép Apache-2.0. Điều này là tốt, nhưng vì Prisma có nhà đầu tư, tôi sẽ không ngạc nhiên nếu họ làm giống MongoDB khi nói đến giấy phép của họ.

Nguồn