PostgreSQL 在大量數據庫中的表現如何?
我們有一個 Web 應用程序,其架構要求任何註冊使用者(實際上是一家公司)都應該與其他使用者隔離,即,我將使用相同的數據模型執行相同的 Web 應用程序,但為每個客戶使用不同的數據集。
因此,我們確實考慮在 Postgres 中為每個客戶創建不同的數據庫。該解決方案是否可以擴展到 10-20K 個數據庫?多好?
有沒有人對此有更好的解決方案?
提前致謝。
在低端,它基本上歸結為“你能絕對說你沒有共享數據嗎?” 與mysql不同,數據庫是postgresql中的一個絕對邊界。如果您
SELECT zip_code FROM common.city_zip WHERE city=...
使用單獨的數據庫(至少不是沒有dblink
),則不能。如果你有任何共享數據,postgresql 的“模式”類似於 mysql 所說的“數據庫”。你可以
CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
。您將為每個客戶端創建一個架構,該客戶端的使用者將在其搜尋路徑中首先擁有其架構,並且將授予權限,以便客戶端 A 的使用者可以訪問clienta
和public
架構(及其表)。您的問題將是在客戶端數量的高端,每個表都儲存為一個文件,因此無論您使用每個客戶端一個數據庫,每個客戶端一個模式,還是使用類似
${client}_customer
表名的名稱,您都會即使每個客戶端只有一個表(每個連接加上一個文件描述符),也可能會遇到 10k 個客戶端的文件描述符限制。當然,您可以使用 sysctl 動態調整核心的最大文件描述符數,但是如果您第一次將每個程序的限制 (ulimit) 設置得太低,則需要重新啟動 postgresql。另一種方法是使用“一個大表”,其中包含一個客戶端列,該列標識該行屬於哪個客戶端(理想情況下,如果每個客戶端有一個使用者,則通過使用者名,這使得下面的東西更容易)。通過不授予客戶端對該表的任何訪問權限,您可以創建特定於客戶端的視圖(或用於
session_user
標識目前客戶端)。但是,不能直接通過視圖進行更新。您需要定義用於在表上插入/更新/刪除的函式(每個客戶端一組函式或使用session_user
),這些函式SECURITY DEFINER
用於作為具有在表上插入/更新/刪除權限的特殊使用者執行(注意:session_user
使用,因為user
和current_user
基於目前上下文,並且在 SECURITY DEFINER 函式中,這始終是定義函式的使用者)。性能方面,除了 fd 問題,老實說,我不知道在 postgresql 中使用 10000 個數據庫會發生什麼,而不是在其中擁有一個包含 10000 個客戶價值數據的大表。適當的索引設計應該避免大表查詢緩慢。
我會說我在這里為每個客戶端使用了單獨的數據庫(我們添加伺服器以保持系統可用,根據需要將客戶端數據庫轉移到新伺服器,因此我們永遠不會在一台伺服器上達到 10k 個數據庫)。我不得不定期從備份中恢復個別客戶的數據以進行調試或由於使用者錯誤,這對於“一張大桌子”設計來說絕對是一場噩夢。此外,如果您打算向您的客戶銷售您的產品定制,那麼“一張大桌子”設計可能最終會阻礙您定制數據模型的能力。