表单数据分表解决方案
整体思路
数据可以根据 映射表找到对应的数据表单
需求分析
总开关设计
有一个 总开关,打开走 分表方案, 关闭走不分表
新增租户功能
提供一个接口,新增租户功能
- 检查 总开关,关闭直接返回成功
- 提供一个算法(参照新增租户算法部分),把新租户放入到以前表中或者放到新建表中
- 放入以前表中:在映射表中新增一条记录
- 放到新建表中:
- 新建数据表单
- 在新建数据表单中新增一条记录
删除租户功能
提供一个接口,删除租户功能
- 检查 总开关,关闭直接返回成功
- 直接在映射表中删除对应的记录,没有找到报错(软删除)
数据的增删改查
-
检查 总开关,关闭直接 走 单表的增删改查
-
增加数据
- 判断租户是否在,不存在 走 新增租户功能
- 存在,通过解析器,找到对应表,存入数据
-
删除数据
- 判断租户是否在,不存在 报错
- 存在,通过解析器,找到对应表,删除数据
-
查询数据
- 判断租户是否在,不存在 报错
- 存在,通过解析器,找到对应表,查询数据
-
修改数据
- 判断租户是否在,不存在 报错
- 存在,通过解析器,找到对应表,修改数据
表结构
映射表
字段 | 字段名 | 说明 |
---|---|---|
Id | Id | 主键 |
TenantId | 租户Id | |
FormType | 表单类型 | |
TableName | 表单名称 | |
TenantLevel | 租户级别 | |
CreateTime | 创建时间 | |
IsDelete | 删除标记 |
表单数据表
字段 | 字段名 | 说明 |
---|---|---|
Id | Id | 主键 |
TenantId | 租户Id | |
FormType | 表单类型 | |
…… |
算法
新增租户算法
根据租户等级来决定 租户占表的百分比
- 等级规则:1级, 2级, …,以此类推, 最高10级
- 占比规则:表中所有租户累计占比不得 超过 10
具体算法:
// 给定一个 租户等级
var tenantLevel = 1;
// 把规则表中数据取出,并以 TableName 分组,并计算出可以放下当前租户的 TableName
var list = dbContext.Db.Queryable<TableDictEntity>().ToList();
var dictItem = list.GroupBy(e => e.TableName)
.Select(g => new {tableName = g.Key, sum = g.Sum(e =>e.TenantLevel)})
.First(g => g.sum <= 10 - tenantLevel);
if(dictItem == null) // 说明当前 表已经都饱和了
{
// 需要 新建一个表单表
dbContext.Db.MappingTables.Add(nameof(Entity), nameof(Entity) + DateTime.Now.ToString("yyyyMMddHHmmss"));
}
// 在映射表中新增一条记录
……
后续
- 数据增长速率的统计
- 定时任务迁移数据
- 分配算法的优化