Thiết kế Kiến trúc Cơ sở dữ liệu SaaS

Những quyết định sai lầm về cơ sở dữ liệu trong tuần đầu tiên sẽ ám ảnh bạn trong nhiều năm.

Một nhà sáng lập SaaS cần một schema có khả năng xử lý đa người dùng (multi-tenancy), thanh toán và sự tăng trưởng. Nếu làm sai, bạn sẽ phải viết lại toàn bộ hệ thống của mình trong vòng sáu tháng.

Dưới đây là cách xây dựng một schema sẵn sàng cho môi trường production.

  1. Chọn Chiến lược Tenant

Bạn phải cô lập dữ liệu giữa các khách hàng.

• Row-level (Dùng chung DB): Độ phức tạp thấp. Tốt nhất cho hầu hết các startup. Sử dụng bộ lọc WHERE organization_id = ? trong mọi truy vấn. • Schema-level (Các Schema riêng biệt): Độ phức tạp trung bình. Phù hợp cho các nhu cầu về quy định/pháp lý. • Database-level (Các DB riêng biệt): Độ phức tạp cao. Tốt nhất cho các khách hàng doanh nghiệp (enterprise).

Đối với 90% các sản phẩm mới, multi-tenancy ở cấp độ hàng (row-level) là lựa chọn đúng đắn.

  1. Phân cấp Thực thể Chính xác

Đừng tính phí người dùng trực tiếp. Người dùng có thể đến và đi. Tổ chức (Organization) mới là thứ tồn tại lâu dài.

Phân cấp nên trông như thế này: User ── MemberOf ── Organization ── Subscription ── Invoice

• Users: Chỉ dùng bảng này để định danh. Sử dụng UUID để ngăn chặn các cuộc tấn công. • Organizations: Đây là ranh giới tenant của bạn. Luôn liên kết các gói đăng ký (subscriptions) với tổ chức. • Memberships: Sử dụng một bảng trung gian (join table) để liên kết người dùng với các tổ chức. Lưu trữ vai trò (roles) tại đây, thay vì lưu trong bảng người dùng.

  1. Thanh toán và Gói đăng ký

Đừng bao giờ sử dụng một biến boolean đơn giản như is_active. Điều này sẽ tạo ra dữ liệu hỗn loạn.

Hãy sử dụng một máy trạng thái (state machine) cho các gói đăng ký. Các trạng thái phổ biến bao gồm: • trialing • active • past_due • canceled • expired • incomplete

Điều này cho phép bạn xử lý các lỗi thanh toán và thời gian gia hạn (grace periods) mà không cần phải sửa dữ liệu thủ công.

  1. Tiền tệ và Hóa đơn

Hãy tuân thủ các quy tắc nghiêm ngặt sau để tránh các lỗi tài chính:

• Không bao giờ sử dụng FLOAT hoặc REAL cho tiền tệ. Hãy sử dụng số nguyên (integers) để lưu trữ đơn vị cent. Ví dụ: $29.99 sẽ trở thành 2999. • Sử dụng bảng invoice_line_items. Bạn sẽ cần bảng này cho các báo cáo thuế và hoàn tiền. • Sử dụng bảng usage_events nếu bạn tính phí dựa trên mức độ sử dụng sản phẩm của khách hàng.

  1. Mẹo Hiệu suất

• Đánh index cho các khóa ngoại (foreign keys). • Đánh index cho các cột trạng thái (status columns). • Đánh index cho các cột mốc thời gian (timestamp columns). • Tránh các truy vấn N+1. Sử dụng JOIN để lấy dữ liệu tổ chức và gói đăng ký trong một lần truy vấn duy nhất.

Một schema tốt sẽ "vô hình" khi nó hoạt động trơn tru. Nhưng nó sẽ gây ra thảm họa khi nó thất bại.

Hãy xây dựng cho tổ chức. Sử dụng máy trạng thái. Lưu trữ tiền tệ dưới dạng số nguyên.

Source: https://dev.to/feidou/designing-saas-database-architecture-users-organizations-subscriptions-and-billing-df

Optional learning community: https://t.me/GyaanSetuAi