2010-08-09 76 views
1

我目前正在開發一個SaaS類型的應用程序,對於多租戶,我已經在每個用戶的一個數據庫上進行了安排,每個數據庫都包含用戶有權(已付費)所需功能所需的所有表。 該應用程序旨在捕獲數據(即類似網站分析)並將其呈現給用戶。設計應該能夠擴展到數以萬計的用戶(最終)。多租戶 - 預先創建表或根據需要創建表?

一個可行的解決方案是當應用程序檢測到它們被需要時動態地創建表格嗎?或者我應該創建所有最終在特定用戶數據庫中的所需表格,只要我知道它們可能需要(用戶升級,新功能等)?

我目前的架構將允許我做這樣的事情:

function insertData($table, $data) { 
    mysql_query("INSERT INTO ".$table." VALUES ('".implode("', '", $data)."')"); 
    if (mysql_errno()) { 
     if (mysql_errno() == 1146) { // table does not exist 
     if ($this->createTable($table)) { 
      $this->insertData($table, $data) 
     } 
     } else { 
     // other errors 
     } 
    } 
} 

我想的靈活性,能夠添加功能,而無需通過所有用戶數據庫具有循環來添加表,所以設置像上述將幫助我實現這一點。但是我不確定我是否錯過了會讓我後悔做出決定的事情?

回答

0

使用insert來測試表是否存在可能不是最佳選擇,特別是考慮到數據庫服務器的行大小和延遲。一個更好的解決辦法可能是使用「節目表」,即:

SHOW TABLES LIKE 'TABLENAME'; 

中的結果將是這樣的:

Tables_in_DATABASENAME (TABLENAME) 
---------------------------------- 
be_groups 

如果行數是零,顯然是表不存在。

就您的過程而言 - 我想我會採取混合方法。當客戶升級時,並且作爲供應工作流的一部分,創建向客戶提供新服務所需的所有表。這樣,客戶不會佔用更多的資源(在這種情況下主要是磁盤),而不會動搖自己的資源調配痛苦。

+0

謝謝你的回答。我寫的代碼的好處是,測試表是否存在只有在查詢首先出現錯誤時纔會執行。一旦表被創建,最初的INSERT查詢就會無誤地運行。擁有SHOW TABLES,需要我每次運行INSERT時都檢查一次。 我同意我們關於在升級時創建表的評論,但如果新功能添加到系統中,我仍然必須遍歷所有數據庫。 – 2010-08-09 21:32:55

+0

不一定,這取決於您的帳戶結構如何設置。我讀'通過所有數據庫循環'爲'檢查每個數據庫,不管用戶的帳戶級別';實際上,根據用戶的ACL,您已經知道哪些數據庫需要升級。如果你關心升級的服務器負載,創建空表幾乎不需要加載--MySQL基本上是創建文件和更新索引。即便如此,您可以考慮交錯部署和/或專門的維護窗口。 – 2010-08-09 22:03:54

+0

我會承認插入/錯誤/創建週期與配置可能是比其他任何事情更個人化的選擇,但我覺得很像在一張不在那裏的桌子上放一杯果汁,注意到溢出,去拿桌子,然後重新開始。更容易先看看桌子。 – 2010-08-09 22:05:42