Tôi khuyên bạn nên tìm kiếm thông tin trên danh sách gửi thư PostgreSQL về thiết kế nhiều người thuê. Đã có rất nhiều cuộc thảo luận ở đó, và câu trả lời tóm lại là "nó phụ thuộc". Có mọi cách đánh đổi giữa tính cách ly được đảm bảo, hiệu suất và khả năng bảo trì.
Cách tiếp cận phổ biến là sử dụng một cơ sở dữ liệu duy nhất, nhưng một lược đồ (không gian tên) cho mỗi khách hàng có cùng cấu trúc bảng trong mỗi lược đồ, cộng với một lược đồ dùng chung hoặc chung cho dữ liệu giống nhau trên tất cả chúng. Một lược đồ PostgreSQL giống như một "cơ sở dữ liệu" MySQL ở chỗ bạn có thể truy vấn trên các lược đồ khác nhau nhưng chúng bị cô lập theo mặc định. Với dữ liệu khách hàng trong lược đồ riêng biệt, bạn có thể sử dụng search_path
cài đặt, thường thông qua ALTER USER
customername SET search_path ='customerchema, sharedschema'
để đảm bảo mỗi khách hàng nhìn thấy dữ liệu của họ và chỉ dữ liệu của họ.
Để được bảo vệ thêm, bạn nên REVOKE
TẤT CẢ TỪ SCHEMA danh mục khách hàng TỪ công khai
thì GRANT
TẤT CẢ KHÁCH HÀNG TRÊN SCHEMA ĐẾN khách hàng
vì vậy họ là người duy nhất có quyền truy cập vào nó, làm như vậy với mỗi bảng của họ. Nhóm kết nối của bạn sau đó có thể đăng nhập bằng tài khoản người dùng cố định có không GRANT
ed truy cập vào bất kỳ giản đồ khách hàng nào nhưng có quyền ĐẶT VAI TRÒ
để trở thành bất kỳ khách hàng nào. (Làm điều đó bằng cách trao cho họ tư cách thành viên của từng vai trò khách hàng với NOINHERIT được thiết lập để các quyền phải được xác nhận một cách rõ ràng qua SET ROLE
). Kết nối sẽ ngay lập tức SET ROLE
cho khách hàng mà nó hiện đang hoạt động. Điều đó sẽ cho phép bạn tránh phải tốn công tạo kết nối mới cho từng khách hàng trong khi vẫn duy trì khả năng bảo vệ mạnh mẽ chống lại lỗi lập trình viên dẫn đến truy cập nhầm dữ liệu của khách hàng. Miễn là nhóm thực hiện TỪ CHỐI TẤT CẢ
và / hoặc ĐẶT LẠI VAI TRÒ
trước khi chuyển giao các kết nối cho ứng dụng khách tiếp theo, điều đó sẽ cung cấp cho bạn sự cô lập rất mạnh mà không gây khó chịu cho các kết nối riêng lẻ cho mỗi người dùng.
Nếu môi trường ứng dụng web của bạn không được tích hợp sẵn nhóm kết nối phù hợp (giả sử bạn đang sử dụng PHP với các kết nối liên tục) thì bạn thực sự cần đặt nhóm kết nối tốt
ở vị trí giữa Pg và máy chủ web, vì quá nhiều kết nối đến phần phụ trợ sẽ ảnh hưởng đến hiệu suất của bạn. PgBouncer
và PgPool-II
là những lựa chọn tốt nhất và bạn có thể dễ dàng thực hiện BỎ TẤT CẢ
và ĐẶT LẠI VAI TRÒ
cho bạn trong quá trình kết nối.
Nhược điểm chính của cách tiếp cận này là chi phí duy trì nhiều bảng, vì tập hợp các bảng không chia sẻ cơ sở của bạn được sao chép cho từng khách hàng. Nó sẽ tăng lên khi số lượng khách hàng tăng lên, đến mức mà số lượng bảng tuyệt đối để kiểm tra trong quá trình chạy autovacuum bắt đầu trở nên đắt đỏ và ở đó bất kỳ hoạt động nào dựa trên tổng số bảng trong DB đều bị chậm lại. Đây là một vấn đề nhiều hơn nếu bạn đang nghĩ đến việc có nhiều hàng nghìn hoặc hàng chục nghìn khách hàng trong cùng một DB, nhưng tôi mạnh mẽ khuyên bạn nên thực hiện một số kiểm tra tỷ lệ với thiết kế này bằng cách sử dụng dữ liệu giả trước khi thực hiện.
Cách tiếp cận lý tưởng có thể là các bảng đơn với bảo mật cấp hàng tự động kiểm soát khả năng hiển thị của tuple, nhưng tiếc là đó là thứ mà PostgreSQL chưa có. Có vẻ như nó đang được triển khai nhờ công việc SEPostgreSQL bổ sung cơ sở hạ tầng và API phù hợp, nhưng nó không phải ở phiên bản 9.1.