在低端(500个租户/ 10000个用户),这就是我的方法。首先,您有一个“控制”数据库,该数据库是全局的,集中的数据库,其中包含有关租户和用户的所有信息(我真的不认为您希望以SQL身份验证登录名来管理这些信息)。因此,想象一下一个名为“ Control”的数据库,其中包含以下表格:
CREATE TABLE dbo.Instances
(
InstanceID INT PRIMARY KEY,
Connection VARCHAR(255)
--, ...
);
INSERT dbo.Instances SELECT 1, 'PROD1\Instance1';
INSERT dbo.Instances SELECT 1, 'PROD2\Instance1';
-- ...
CREATE TABLE dbo.Tenants
(
TenantID INT PRIMARY KEY,
Name NVARCHAR(255) NOT NULL UNIQUE,
InstanceID INT -- Foreign key tells which instance this tenant's DB is on
--, ...
);
INSERT dbo.Tenants SELECT 1, 'MyTenant', 1;
-- ...
CREATE TABLE dbo.Users
(
UserID INT PRIMARY KEY,
Username VARCHAR(320) NOT NULL UNIQUE,
PasswordHash VARBINARY(64), -- because you never store plain text, right?
TenantID INT -- foreign key
--, ...
);
INSERT dbo.Users SELECT 1, 'foo@bar.com', 0x43..., 1;
在我们的例子中,当我们添加一个新的租户时,我们将动态地构建数据库,但是当管理员用户在UI中单击“确定”时就不会动态地构建数据库。 ,然后依次创建每个新数据库。我们这样做是为了(a)防止管理员用户等待数据库创建,以及(b)避免两个管理员用户试图同时创建数据库或以其他方式被拒绝锁定模型的能力(在创建新数据库时需要) )。
使用名称方案(Tenant000000xx
在其中xx
表示)创建数据库Tenants.TenantID
。这使得维护工作很容易,而不是有各种命名数据库BurgerKing
,McDonalds
,KFC
等不是因为我们是在快餐,只是使用作为一个例子。
我们没有按注释建议预先分配数千个数据库的原因是,我们的管理员用户通常对租户的规模,是否具有高优先级等有一些了解。因此,他们在UI中有一些基本选择,将决定其初始大小和自动增长设置,其数据/日志文件将进入哪个磁盘子系统,它们的恢复设置,取决于其的备份计划,甚至还可以明智地将数据库部署到哪个实例,以最佳地平衡使用率(尽管我们的管理员可以覆盖此设置)。创建数据库后,将使用所选实例更新租户表,为租户创建一个admin用户,并通过电子邮件向我们的管理员发送凭据以将其传递给新租户。
如果您使用的是单个入口点,则不允许多个租户拥有具有相同用户名的用户是不可行的。我们选择使用电子邮件地址,如果所有用户都在公司工作并使用他们的公司电子邮件地址,则可以使用该地址。尽管我们的解决方案最终变得更加复杂,原因有两个:
- 我们有为多个客户服务的顾问,并且需要访问多个
- 我们有一些房客,他们实际上实际上是由多个房客组成的
因此,我们最终得到了一个TenantUsers
表,该表允许一个用户与多个租户关联。
最初,当用户登录时,应用程序将仅知道控制数据库的连接字符串。登录成功后,它便可以根据找到的信息建立连接字符串。例如
SELECT i.Connection
FROM dbo.Instances AS i
INNER JOIN dbo.Tenants AS t
ON i.InstanceID = t.InstanceID
INNER JOIN dbo.TenantUsers AS u
ON i.TenantID = u.TenantID
WHERE u.UserID = @UserID;
现在,该应用程序可以连接到用户的数据库(每个用户都有一个默认租户),或者用户可以从他们可以访问的任何租户中进行选择。然后,该应用程序将简单地检索新的连接字符串,并重定向到该租户的主页。
如果您建议使用这个10毫米的用户区域,则肯定需要更好地平衡它。您可能希望联合应用程序,以便它们具有连接到不同控制数据库的不同入口点。如果为每个租户提供一个子域(例如TenantName.YourApplicationDomain.com),则可以在幕后使用DNS /路由进行此操作,而无需在需要进一步扩展时中断它们。
除此之外,还有很多-像@Darin一样,我只是在这里挠表面。让我知道您是否需要免费咨询。:-)