Ở cấp độ thấp, về cơ bản, nó sôi lên "bạn hoàn toàn có thể nói rằng bạn không có dữ liệu chia sẻ?" Không giống như mysql, cơ sở dữ liệu là một ràng buộc tuyệt đối trong postgresql. Bạn không thể SELECT zip_code FROM common.city_zip WHERE city=...
nếu bạn đi với cơ sở dữ liệu riêng biệt (ít nhất là không có dblink
).
Nếu bạn có bất kỳ dữ liệu chia sẻ nào, "lược đồ" của postgresql tương tự như cái mà mysql gọi là "cơ sở dữ liệu" . Bạn có thể CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
. Bạn sẽ tạo một lược đồ cho mỗi khách hàng, người dùng của khách hàng đó sẽ có lược đồ của họ trước trong đường dẫn tìm kiếm của họ và quyền sẽ được cấp để người dùng của Khách hàng A có quyền truy cập vào clienta
và public
lược đồ (và bảng của họ).
Vấn đề của bạn sẽ là ở cấp cao của # khách hàng, mỗi bảng được lưu dưới dạng tệp, do đó, dù bạn đi với một cơ sở dữ liệu cho mỗi khách hàng, một lược đồ cho mỗi khách hàng hay sử dụng một cái gì đó như ${client}_customer
cho tên bảng của bạn, bạn sẽ có khả năng chạy vào giới hạn filedescriptor với 10k khách hàng ngay cả khi bạn chỉ có một bảng cho mỗi khách hàng (cộng với một filedescriptor cho mỗi kết nối). Tất nhiên, bạn có thể điều chỉnh số lượng mô tả tệp tối đa của hạt nhân một cách nhanh chóng bằng sysctl, nhưng giới hạn cho mỗi quá trình (ulimit) sẽ yêu cầu khởi động lại postgresql nếu bạn đặt nó quá thấp trong lần đầu tiên.
Cách khác là có "một bảng lớn" với một cột máy khách xác định hàng đó thuộc về khách hàng nào (lý tưởng nhất là theo tên người dùng nếu bạn có một người dùng cho mỗi khách hàng, điều này làm cho công cụ bên dưới RẤT dễ dàng hơn). Bằng cách không cấp bất kỳ quyền truy cập nào cho bảng này của khách hàng, bạn có thể tạo các chế độ xem cụ thể của khách hàng (hoặc sử dụng session_user
để xác định ứng dụng khách hiện tại). Cập nhật không thể được thực hiện trực tiếp thông qua một cái nhìn, mặc dù. Bạn sẽ cần phải có các hàm được xác định để chèn / cập nhật / xóa trên bảng (một bộ hàm cho mỗi máy khách hoặc người khác sử dụng session_user
) với các hàm sử dụng SECURITY DEFINER
để thực thi như một người dùng đặc biệt có quyền chèn / cập nhật / xóa trên các bảng (lưu ý : session_user
được sử dụng vì user
vàcurrent_user
được dựa trên bối cảnh hiện tại và trong hàm DEFINER AN NINH, đây sẽ luôn là người dùng xác định hàm).
Hiệu suất khôn ngoan, ngoài vấn đề fd, tôi thực sự không biết điều gì sẽ xảy ra với 10000 cơ sở dữ liệu trong postgresql, so với việc có một bảng lớn với 10000 dữ liệu của khách hàng trong đó. Thiết kế chỉ mục phù hợp sẽ giữ cho bảng lớn không bị chậm truy vấn.
Tôi sẽ nói rằng tôi đã đi với cơ sở dữ liệu riêng biệt cho từng khách hàng ở đây (chúng tôi thêm máy chủ để giữ cho hệ thống có thể sử dụng được, chuyển cơ sở dữ liệu khách sang máy chủ mới khi cần, vì vậy chúng tôi sẽ không bao giờ nhận được cơ sở dữ liệu 10k trên một máy chủ). Tôi đã phải khôi phục dữ liệu của từng khách hàng từ các bản sao lưu để gỡ lỗi hoặc do lỗi người dùng thường xuyên, điều gì đó sẽ là một cơn ác mộng tuyệt đối trên thiết kế "một bàn lớn". Ngoài ra, nếu bạn có ý định bán tùy chỉnh sản phẩm của mình cho khách hàng, thiết kế "một bàn lớn" có thể sẽ khiến bạn phải bối rối về khả năng tùy chỉnh mô hình dữ liệu.