数据库分库
数据库分库(或者叫“拆分数据库”)通常有2种做法:
- 按业务边界垂直拆分
- 按用户水平拆分
Nebula同时支持这2种做法:
- 垂直拆分:在Nebula中称为“应用库”拆分,也就是某个应用单独操作某个数据库
- 水平拆分:Nebula支持按客户来拆分数据库(客户隔离),拆分后的数据库被称为“租户库”
注册应用库
应用库在配置服务中就是一个普通的数据库连接,如下图所示:
在表格中,Name 列的名称将在代码中被引用。
连接到应用库
public async Task<string> Test4()
{
// 连接到 某个特定的 【应用库】
// xxx_Db 是一个连接名称,在【配置服务】中有对应的连接设置
using( DbContext dbContext = this.CreateAppDbConnection("xxx_Db") ) {
return await dbContext.CPQuery.Create("select now()").ExecuteScalarAsync<string>();
}
}
有2种方法连接到【应用库】
- 调用 BaseController.CreateAppDbConnection("name") 方法
- 调用 DbConnManager.CreateAppDb("name") 方法
注册租户库
这里又分为2个步骤:
- 为租户的数据库实例注册数据库连接
- 为每个租户指定连接名字
这里假设所有租户的数据库部署在3个数据库实例上,
我们就可以分别为它们创建3个数据库连接:yunwei-s1, yunwei-s2, yunwei-s3
在tenantconn表中,可以为每个租户指定与数据库实例的映射关系。
连接到租户库
可参考下面示例代码:
public async Task<string> Test1()
{
// 从请求中获取到的租户信息
// 通常是登录操作,此时用户还没有经过登录验证,这时候需要在提交登录数据时把 租户ID 一起发送到服务端
// 服务端根据 租户ID 就可以连接到相应的租户库
string tenantId = "xxxxxxxxxx";
using( DbContext dbContext = this.CreateTenantConnection(tenantId) ) { // 连接到 指定的【租户库】
return await dbContext.CPQuery.Create("select now()").ExecuteScalarAsync<string>();
}
}
public async Task<string> Test2()
{
// 连接到 与当前用户对应的 【租户库】
using( DbContext dbContext = this.CreateTenantConnection() ) {
return await dbContext.CPQuery.Create("select now()").ExecuteScalarAsync<string>();
}
}
或者直接调用 DbConnManager.CreateTenant 方法:
/// <summary>
/// 根据 租户ID 创建对应的SQL数据库连接
/// </summary>
/// <param name="tenantId">租户ID</param>
/// <param name="readonlyDB">是否连接【只读库】</param>
/// <returns></returns>
public static DbContext CreateTenant(string tenantId, bool readonlyDB = false)