数据库分库

数据库分库(或者叫“拆分数据库”)通常有2种做法:

  • 按业务边界垂直拆分
  • 按用户水平拆分

Nebula同时支持这2种做法:

  • 垂直拆分:在Nebula中称为“应用库”拆分,也就是某个应用单独操作某个数据库
  • 水平拆分:Nebula支持按客户来拆分数据库(客户隔离),拆分后的数据库被称为“租户库”



注册应用库

应用库在配置服务中就是一个普通的数据库连接,如下图所示:
xx

在表格中,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个步骤:

  • 为租户的数据库实例注册数据库连接
  • 为每个租户指定连接名字

xx
这里假设所有租户的数据库部署在3个数据库实例上,
我们就可以分别为它们创建3个数据库连接:yunwei-s1, yunwei-s2, yunwei-s3

xx
在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)