2014-01-18 64 views
1

我們有一個SaaS應用程序,每個租戶在Postgres中都有自己的數據庫。我如何將補丁應用於所有數據庫?例如,如果我想添加一個表或向表中添加一列,我必須編寫一個循環遍歷所有數據庫的程序,並針對它們或使用pgadmin執行一個SQL,然後逐個查看它們。Postgres多租戶管理/維護

有更智能和/或更快的方式嗎?

任何幫助,非常感謝。

回答

3

是的,有一個更聰明的方法。

不要爲每個租戶創建新的數據庫。如果一切都在一個數據庫中,那麼你只需要改變一個數據庫。

選擇一個數據庫,將每個表修改爲具有列TENANT並將其添加到主鍵。然後將所有租戶的每個記錄插入到該數據庫中,並刪除其他數據庫(顯然,需要更多的工作,因爲您的應用程序需要更改)。

與方法的差異被廣泛別處討論:

如果你不把所有東西都放在一個數據庫中,那麼恐怕你必須單獨改變它們,編程方式是最簡單的。

+0

感謝您的回答。請記住,對於已經投產的系統,我不能只是徹底檢修設計。此外,爲每個租戶分開數據庫是爲了保護每個客戶的數據。 那裏有工具或庫,已經做了我需要的東西嗎? – Rex

+0

在這種情況下,您已經通過編寫一些代碼來循環訪問databases @ user2182414來完成最簡單的操作。 – Ben

2

在一個較高的水平,所有的多租戶應用程序遵循三種方法之一:在一個數據庫中

  1. 一個租戶的數據生命,
  2. 一個租戶的數據存在於一個模式,或
  3. 添加一個tenant_id/account_id列到您的表(共享模式)。

我通常會發現開發人員在評估這些不同的方法時使用以下標準。

隔離:由於您可以將每個承租人一手放入自己的數據庫中,並讓租戶在另一個承租人上共享相同的表,因此這成爲最明顯的維度。如果您向用戶提供原始SQL訪問權限,或者您處於受監管的行業(如醫療保健),則可能需要從數據庫獲得嚴格的保證。也就是說,PostgreSQL 9.5帶有行級安全策略,這使得大多數應用程序對此不那麼關注。

可擴展性:如果您的租戶共享相同的架構(方法#3),並且租戶的字段在他們之間不同,那麼您需要考慮如何合併這些字段。

這篇關於multi-tenant databases的文章總結了不同的方法。例如,您可以添加十幾列,將它們稱爲C1,C2等等,並讓您的應用程序根據tenant_id推斷此列中的實際數據。 PostgresQL 9.4帶有JSONB支持,本地允許您使用半結構化字段來表示不同租戶數據之間的差異。

縮放:另一個標準是數據庫如何輕鬆地向外擴展。如果您爲每個數據庫或架構創建租戶(上面的#1或#2),則您的應用程序可以使用現有的Ruby Gems或[Django包] [1]來簡化應用程序集成。也就是說,您需要手動管理租戶的數據和他們居住的機器。同樣,您需要構建自己的分片邏輯來傳播外鍵約束和ALTER TABLE命令。

使用方法#3,您可以使用現有的開源縮放解決方案,如Citus。例如,this blog post描述瞭如何使用Postgres輕鬆分解多租戶應用程序。

0

現在是我回饋社區的時候了:)所以4年後,我們的多租戶平臺已投入生產,我希望與大家分享以下觀察/體驗。

  1. 我們爲每個租戶使用了一個數據庫。這給了我們極大的靈活性,因爲備份中數據庫的大小並不是很大,因此我們可以輕鬆地將它們導入到客戶問題的登臺環境中。

  2. 我們使用Liquibase進行數據庫開發和升級。這對我們來說是一個巨大的幫助,使我們能夠將整個構建打包成一個簡單的戰爭文件。所有更改都可以非常有效地進行版本管理和管理。這裏有一些學習曲線,但沒有實質性的東西。 2-5天可以顯着節省您的時間。

  3. 鑑於我們使用Spring/JPA/Hibernate,我們使用了一種稱爲動態數據源路由的技術。所以當用戶登錄時,我們通過查找找到相關的數據源,並將它們連接到正確數據庫的會話。這也是Liquibase腳本獲取更新時的情況。

這就是,現在,我會回來更晚。