实现一库多租户模式的方案
:在.NET中实现一库多租户(Single Database Multi-Tenancy)模式,主要通过共享数据库但隔离数据的方式实现。以下是几种常见实现方法:
具体实现可参考NetCoreKevin的Kevin.EntityFrameworkCore模块
基于NET8构建的现代化Saas企业级WebAPI架构,采用前后端分离设计:
- 前端:Vue3框架 - 认证授权:IDS4单点登录系统
- 架构特性:
- DDD领域驱动设计
- 多级缓存机制
- 分布式系统支持
- 一库多租户实现
- 核心技术集成:
- CAP事件总线
- SignalR实时通信
- IOC模块化依赖注入
- 任务调度:
- Quartz自动任务
- 多短信平台集成
- AI智能体:
- AgentFramework
- SemanticKernel
- 其他功能:
- API多版本管理
- 单元测试框架
- RabbitMQ消息队列
项目地址:github:https://github.com/junkai-li/NetCoreKevin
Gitee: https://gitee.com/netkevin-li/NetCoreKevin
共享表+租户ID列
在每张表中添加TenantID列,查询时自动过滤租户数据。
// 实体基类
public abstract class TenantEntity
{public int TenantId { get; set; }
}// 查询过滤
var tenantProducts = dbContext.Products.Where(p => p.TenantId == currentTenantId);
EF Core可通过全局查询过滤器自动实现:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{modelBuilder.Entity<Product>().HasQueryFilter(p => p.TenantId == _tenantProvider.GetTenantId());
}
动态Schema
每个租户使用独立的数据库Schema,表结构相同但数据隔离。
// 动态设置Schema
modelBuilder.HasDefaultSchema(tenantSchema);// 或针对特定实体
modelBuilder.Entity<Product>().ToTable("Products", tenantSchema);
SQL Server创建Schema示例:
CREATE SCHEMA tenant1;
CREATE TABLE tenant1.Products (...);
行级安全(RLS)
使用数据库原生行级安全策略(SQL Server/PostgreSQL支持)。
SQL Server示例:
CREATE SECURITY POLICY TenantFilter
ADD FILTER PREDICATE dbo.fn_tenantPredicate(TenantId) ON dbo.Products;
应用代码只需正常查询,数据库自动过滤。
实现要点
租户识别
- 通过子域名识别:
tenant1.example.com - JWT声明或Cookie
- 请求头参数
依赖注入
services.AddScoped<ITenantProvider>(sp => new HttpContextTenantProvider(sp.GetService<IHttpContextAccessor>()));
数据库上下文
public class TenantDbContext : DbContext
{private readonly ITenantProvider _tenantProvider;public TenantDbContext(ITenantProvider tenantProvider) {_tenantProvider = tenantProvider;}protected override void OnModelCreating(ModelBuilder modelBuilder){// 应用全局过滤器}
}
性能优化方案
- 索引优化:建议为TenantID字段建立索引,提升查询效率
- 数据分片:对于数据量大的场景,推荐采用分库分表策略
- 缓存机制:引入缓存层,避免高频重复查询数据库
- 数据维护:建立定期清理机制,及时清除无效租户数据
实施建议:共享表结合租户ID的模式是最简单且通用的解决方案,可根据实际业务需求选择最适合的优化方案。