2010-08-09 65 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