多租户 - 预先创建表还是根据需要创建表?
我目前正在开发一种 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
}
}
}
我希望能够灵活地添加功能,而不必循环遍历所有用户数据库来添加表,因此像上面这样的设置将帮助我实现这一目标。但我不确定我是否错过了一些会让我以后后悔这个决定的事情?
I'm currently working on a SaaS type application, and for multi-tenancy I've settled on one database per user, with each database containing all tables required by the functionality the user is entitled to (have payed for).
The application is designed to capture data (i.e. like web analytics) and present it for the user. The design should be able to scale to the tens of thousands of users (eventually).
Would a viable solution be to create the tables 'dynamically' when the application detects they are required? Or should I create all eventually required tables in specific user databases, as soon as I know they may be needed (user upgrade, new features, etc.)?
My current architecture would allow me to do something like this:
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
}
}
}
I would like the flexibility to be able to add functionality without having to loop through all user databases to add tables, so a setup like the above would help me achive that. But I'm not sure if I'm missing something that would make me regret the decision later?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用插入来测试表是否存在可能不是您的最佳选择,特别是考虑到行的大小和数据库服务器的延迟。更好的解决方案可能是使用“显示表”,即:
结果集将如下所示:
如果行数为零,则显然该表不存在。
就你的流程而言——我想我会采取混合方法。当客户升级时,作为配置工作流程的一部分,创建向客户提供新服务所需的所有表。这样,客户就不会占用比他们支付的资源更多的资源(在本例中主要是磁盘),并且您不会给自己带来动态配置的痛苦。
Using an insert to test whether a table exists may not be your best bet, particularly considering the size of the row and latency to the database server. A better solution might be to use 'show tables', i.e.:
The resultset will be something like this:
If the number of rows is zero, clearly the table does not exist.
As far as your process is concerned -- I think I'd take a hybrid approach. When the customer upgrades and as part of your provisioning workflow create all the tables needed to provide the new services to the customer. That way the customer doesn't take up any more resources (disk mainly, in this case) than they're paying for, and you're not causing yourself the pain of provisioning dynamically.