Nguồn: PlanetScale Blog

Tóm tắt

Bài viết từ PlanetScale phân tích ba chiến lược phổ biến cho multi-tenancy trong Postgres: shared-schema (chia sẻ bảng, phân tách bằng cột tenant_id), schema-per-tenant (mỗi tenant có schema riêng), và database-per-tenant (mỗi tenant có logical database riêng). PlanetScale khuyến nghị rõ ràng shared-schema là phương pháp mặc định và là cách duy nhất đạt multi-tenancy thực sự — hai phương pháp còn lại chỉ chia sẻ tài nguyên, không chia sẻ bảng.

Với shared-schema, mọi tenant dùng cùng tập bảng, dữ liệu được cô lập bằng một cột như tenant_id kiểu BIGINT. Điểm quan trọng là tenant_id phải đứng đầu trong hầu hết các index để query planner có thể loại trừ partition không liên quan. Khi scale lên hàng nghìn tenant, bảng lớn có thể được partition theo tenant_id để tối ưu thêm. Schema migration chỉ cần chạy một lần cho tất cả tenant.

Bài viết cảnh báo về rủi ro chính của shared-schema: mọi query đều phải có WHERE tenant_id = ?. Thay vì dựa vào developer nhớ thêm filter, nên dùng ORM global scopes, middleware, hoặc shared data access layer để inject filter tự động. Postgres Row-Level Security (RLS) được đề cập như một lớp bảo vệ bổ sung nhưng không được khuyến nghị làm lớp chính — logic security trong database khó debug và dễ bị misconfigure khi dùng với connection pooling.

Schema-per-tenant và database-per-tenant phù hợp khi các tenant thực sự cần schema khác nhau, hoặc khi compliance yêu cầu cô lập hoàn toàn. PlanetScale cũng hướng dẫn cách migrate từ schema-per-tenant sang shared-schema cho các dự án đang vận hành, bao gồm cách đặt tên bảng tenants với BIGINT primary key thay vì text identifier để so sánh hiệu quả hơn.

👉 Đọc bài gốc