Sequelize so với Prisma
Bắt đầu
Hiện 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. Đây là một dự án rất khó khăn nhưng tôi rất hào hứng được trực tiếp đối mặt với nó. 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, việc sử dụng một ORM sẽ là tốt nhất vì cơ sở mã vốn đã được thiết kế để sử dụng Mongoose. Nhưng bây giờ thách thức là, ORM nào sẽ là tốt nhất cho cơ sở mã của chúng tôi? Trong bài viết 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 bài viết này do tính chất mối quan hệ của tôi với chủ lao động.
Yêu cầu
Sau khi phân tích kỹ lưỡng nhu cầu của dự án, tôi đã xác định 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 đáp ứng:
- Là một gói JavaScript; vì phần lớn 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 của nó 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 rất 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 để kiểm thử đầy đủ ba ORM khác nhau do thời hạn.
Môi trường kiểm thử
Đối với môi trường kiểm thử của tôi, tôi chạy Postgres thông qua Docker. Tôi lấy bộ dữ liệu lớn nhất và phức tạp nhất của chúng tôi, chuyển nó từ cấu trúc tài liệu sang cấu trúc bảng, và thêm nó vào phiên bản Postgres cục bộ của tôi. Tôi chuyển đổi bộ 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 số cột JSONB.
Từ đó, tôi sẽ viết mã JavaScript sử dụng ORM cụ thể đó và đo lường:
- 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 cặp khóa-giá trị trong một 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 repo cho từng môi trường kiểm thử ORM. Tôi rất muốn chia sẻ các repo 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ả
Vào khoảng ngày 15 tháng 5 năm 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 dùng cho quá trình 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 khi so với Prisma.
- Có tài liệu tốt, dù không được tài liệu hóa tốt bằng tài liệu của Prisma.
Tôi đã chọn Sequelize, nhưng tôi cũng đã tổng hợp một danh sách ưu và nhược điểm cho từng ORM mà 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 với trường hợp sử dụng của bạn hay không.
Ưu và nhược điểm của Sequelize
Ưu điểm:
- Có hàm sync() tự động tạo và xử lý các 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ợ rất nhiều tùy chọn lọc (chẳng hạn như Regex)
- Biểu diễn model/schema được thực hiện bằng JavaScript thô bằng cách sử dụng các lớp, rất dễ tùy biến.
- Sequelize xử lý các kết nối cho (các) cơ sở dữ liệu bạn chọn.
- Sequelize hỗ trợ nhiều kết nối đọc
- Hỗ trợ các truy vấn SQL thô.
- Tính đến ngày 15 tháng 5 năm 2023:
- Trên NPM, Sequelize được cập nhật lần cuối cách đây “14 ngày” và có 1,505,835 lượt tải 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ó thể nó sẽ vẫn là mã nguồn mở trong tương lai gần.
Nhược điểm:
- Biểu diễn model/schema có thể trở nên rất phức tạp và cồng kềnh. Ví dụ, biểu diễn Mongoose của bộ dữ liệu lớn của chúng tôi dài khoảng 262 dòng (bao gồm cả khoảng trắng). Cùng bộ dữ liệu đó khi biểu diễn qua Sequelize là 564 dòng (bao gồm cả khoảng trắng).
- Cú pháp của Sequelize trong một số trường hợp trở nên thật sự khó hiểu và phức tạp.
- Việc di chuyển cơ sở dữ liệu của bạn (chỉnh sửa nó) rất phiền phức. Bạn có thể dùng sequelize-cli để tạo các script mẫu migration bằng JavaScript. NHƯNG, có vẻ như đây cũng là trường hợp tương tự với gần như tất cả các ORM. Di chuyển trong cơ sở dữ liệu quan hệ trong hầu hết trường hợp không hề dễ dàng.
- Tài liệu không tốt lắm. Nó đã tốt hơn nhưng vẫn cần cải thiện. Tuy nhiên với các công cụ như ChatGPT, đây không còn là vấn đề lớn như trước nữa vì ChatGPT có sự hiểu biết rất tốt về Sequelize, có lẽ là do Sequelize đã tồn tại cả một thập kỷ.
- Sequelize không nhạy về kiểu dữ liệu bằng Prisma, điều này có thể dẫn đến 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 vấn đề nhưng đối 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ể tạo schema/model của mình dễ dàng và gọn gàng hơn. Ví dụ, biểu diễn Mongoose của bộ dữ liệu lớn của chúng tôi dài khoảng 262 dòng (bao gồm cả khoảng trắng). Nhưng cùng bộ dữ liệu đó khi được biểu diễn bằng Prisma chỉ dài 221 dòng (bao gồm cả khoảng trắng).
- Prisma có một công cụ CLI giúp việc tạo và di chuyển (sửa đổi) cơ sở dữ liệu của bạn dễ dàng hơn. Điều này rất tiện lợi. Nó không phải là viên đạn bạc nhưng là thứ tốt nhất tôi đã thấy cho đến nay từ một ORM.
- Hỗ trợ các truy vấn SQL thô.
- Mã cho Prisma gọn gàng 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 nó dễ hiểu hơn nhiều so với cú pháp của Sequelize.
- Prisma có một client tự động tạo query builders cho Node.js & TypeScript.
- Tài liệu rất rất tốt và gọn gàng. ChatGPT vẫn có thể giúp nhưng nó không cập nhật về Prisma bằng về Sequelize.
- Tính đến ngày 15 tháng 5 năm 2023:
- Trên NPM, Prisma được cập nhật lần cuối cách đây “6 ngày” và có 1,344,705 lượt tải 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”.
- Theo thử nghiệm của tôi, Prisma chậm hơn đáng kể trong việc tạo các mục của bộ dữ liệu lớn của chúng tôi trong Postgres. Sequelize tạo các mục lớn đó với tốc độ khoảng 2.26 giây cho mỗi mục (tệp JSON). Trong khi Prisma có tốc độ khoảng 11.21 giây cho mỗi mục (tệp JSON). Dựa trên các 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 bộ 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 rất nhiều trong việc xóa một mục ở bộ dữ liệu lớn và phức tạp nhất trong các bài kiểm thử của tôi. Sequelize không có lợi thế so với Prisma khi nói đến việc xây dựng bộ dữ liệu. Cả hai đều phải xử lý một quan hệ sâu ba tầng cho bộ dữ liệu lớn này, vì vậy tôi cho rằng đây là một phép 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 khoản tài trợ 56.5 triệu đô la. 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 thì tốt, nhưng vì Prisma có các nhà đầu tư, tôi sẽ không ngạc nhiên nếu họ đi theo con đường của MongoDB khi nói đến giấy phép của họ.
Nguồn
- https://www.bitovi.com/blog/battle-of-the-node.js-orms-objection-prisma-sequelize
- https://www.prisma.io/docs/orm/more/comparisons/prisma-and-sequelize
- https://github.com/prisma/prisma
- https://github.com/sequelize/sequelize
- https://www.youtube.com/watch?v=rLRIB6AF2Dg
- https://www.youtube.com/watch?v=RebA5J-rlwg
- https://www.youtube.com/watch?v=a5Wh_LDXtLc
- https://www.youtube.com/watch?v=4QN1BzxF8wM