Tôi khuyên bạn nên tìm kiếm thông tin trên danh sách gửi thư của PostgreSQL về thiết kế đa người dùng. Đã có rất nhiều cuộc thảo luận ở đó, và câu trả lời là "nó phụ thuộc". Có sự cân bằng giữa mọi cách giữa sự cô lập, hiệu suất và khả năng bảo trì được bảo đảm.
Cách tiếp cận phổ biến là sử dụng một cơ sở dữ liệu, nhưng một schema (không gian tên) cho mỗi khách hàng có cùng cấu trúc bảng trong từng lược đồ, cộng với lược đồ chung hoặc chung cho dữ liệu giống nhau trên tất cả chúng. Lược đồ PostgreSQL giống như một "cơ sở dữ liệu" MySQL ở chỗ bạn có thể truy vấn trên 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, bạn có thể sử dụng cài đặt search_path
, thường là qua ALTER USER
customername SET search_path = 'customerschema, sharedschema'
để đảm bảo mỗi khách hàng chỉ xem dữ liệu của họ và chỉ dữ liệu của họ.
Để bảo vệ thêm, bạn nên REVOKE
ALL FROM SCHEMA customerschema FROM public
rồi GRANT
ALL ON SCHEMA customerschema TO thecustomer
để chúng là người duy nhất có quyền truy cập vào nó, làm tương tự với từng bảng. Hồ bơi 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ôngGRANT
quyền truy cập ed vào bất kỳ lược đồ khách hàng nào nhưng có quyền SET ROLE
để 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 để quyền đó phải được xác nhận rõ ràng qua số SET ROLE
). Kết nối phải ngay lập tức SET ROLE
cho khách hàng hiện đang hoạt động. Điều đó sẽ cho phép bạn tránh chi phí 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 dẫn đến việc truy cập vào dữ liệu của khách hàng sai. Miễn là hồ bơi có DISCARD ALL
và/hoặc RESET ROLE
trước khi giao kết nối cho khách hàng tiếp theo, điều đó sẽ cung cấp cho bạn sự cách ly rất mạnh mẽ mà không gây thất vọng 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ó một hồ bơi kết nối lắp ráp bên trong (ví dụ, bạn đang sử dụng PHP với kết nối liên tục) sau đó bạn thực sự cần phải đặt một good connection pool ở vị trí giữa Thạc và máy chủ web dù sao, bởi vì quá nhiều kết nối với chương trình phụ trợ sẽ làm tổn thương hiệu suất của bạn. PgBouncer và PgPool-II là các tùy chọn tốt nhất và dễ dàng có thể thực hiện các thao tác DISCARD ALL
và RESET ROLE
cho bạn trong quá trình ngắt kết nối.
Nhược điểm chính của phương pháp này là chi phí đầu tư với việc duy trì nhiều bảng, vì bộ cơ sở của các bảng không được chia sẻ được nhân bản 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 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 có quy mô dựa trên tổng số bảng trong DB chậm lại. Đây là một vấn đề nếu bạn đang nghĩ đến việc có 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ố thử nghiệm mở rộng với thiết kế này bằng cách sử dụng dữ liệu giả trước khi cam kết với nó.
Cách tiếp cận lý tưởng có thể là các bảng duy nhất có tính năng bảo mật cấp hàng tự động kiểm soát mức hiển thị của bộ nhớ, nhưng tiếc là đó là điều mà PostgreSQL chưa có. Dường như nó đang trên đường nhờ công việc của SEPostgreSQL thêm cơ sở hạ tầng và API phù hợp, nhưng nó không phải trong 9.1.
Nguồn
2011-12-09 00:27:26
cảm ơn nhiều !! (xin lỗi, đã làm việc với MySQL gần đây và nó làm cho tôi chết não.) giản đồ nên là một lựa chọn trên nhiều cơ sở dữ liệu - trên thực tế, đã được sử dụng này cho các dự án khác. ý tưởng tuyệt vời về việc thiết lập vai trò sau khi kết nối. đã sử dụng đường dẫn thiết lập, nhưng sự kết hợp của hai là tốt nhất. –
Đúng vậy, việc đặt vai trò cho phép bạn sử dụng bảo mật cấp cơ sở dữ liệu mà không cần phải chịu nhiều đau đớn. Thật tuyệt vời. –
... và nhớ sử dụng một hồ bơi kết nối phong nha như PgPool-II hoặc PgBouncer nếu bạn đang sử dụng một cái gì đó nguyên thủy ở phía máy chủ web như PHP với các kết nối liên tục. Không cần thiết nếu bạn đang sử dụng một cái gì đó giống như một máy chủ ứng dụng Java có kết nối riêng trong máy chủ của nó. –