多租户架构
XYGo Admin 2026-04-01 65 次阅读
表级隔离与字段级隔离的设计理念、优势对比及中间件鉴权流程
多租户架构
XYGo Admin 的多租户系统采用租户专属表族 + 共享数据库的架构模式,兼顾数据隔离性与运维便捷性。
隔离模型
常见方案对比
| 方案 | 隔离粒度 | 数据安全 | 运维成本 | 扩展性 |
|---|---|---|---|---|
| 独立数据库 | 物理级 | 最高 | 高(需管理多库) | 受限 |
| 独立 Schema | 逻辑级 | 高 | 中 | 中 |
| 租户专属表族(本项目) | 表级 | 高 | 低 | 强 |
| 单表 tenant_id 列 | 行级 | 中(依赖查询条件) | 低 | 强 |
本项目的选择:租户专属表族
项目为租户业务定义了一套独立的 xy_tenant_* 表族,与平台级 xy_admin_* 表结构分离:
平台表(管理员体系) 租户表(租户体系)
xy_admin_user xy_tenant_admin
xy_admin_role xy_tenant_role
xy_admin_menu xy_tenant_menu
xy_admin_dept xy_tenant_dept
xy_admin_post xy_tenant_post
xy_admin_notice xy_tenant_notice
同时,部分共享资源表(如附件)通过增加 tenant_id 列实现数据归属标记:
sql
ALTER TABLE xy_sys_attachment ADD COLUMN tenant_id bigint NOT NULL DEFAULT 0;
-- tenant_id = 0 表示平台级数据
相比纯字段级隔离的优势
1. 数据安全边界更清晰
租户核心业务(管理员、角色、菜单、部门等)使用独立表结构,从根本上避免跨租户数据泄漏。即使查询条件遗漏 tenant_id,也不会读到其他租户的数据。
2. 索引效率更高
租户表的主键索引直接按自增 ID 排列,无需为每张表都维护 tenant_id 联合索引。查询时不必在全量数据中做 WHERE tenant_id = ? 过滤,性能更优。
3. 字段与功能独立演进
租户的菜单、角色、权限模型可以独立于平台端扩展字段,互不影响。例如租户菜单可以拥有与平台菜单不同的字段结构。
4. 数据迁移与备份独立
可以只导出 xy_tenant_* 相关表进行租户数据迁移,无需从混合表中按条件抽取。
5. 运维诊断更直观
数据库层面一目了然:xy_tenant_* 是租户数据,xy_admin_* 是平台数据。
租户识别中间件
请求进入后端后,TenantResolve 中间件按以下优先级解析租户身份:
HTTP 请求
→ 1. Header X-Tenant-Id(前端显式传递,优先级最高)
→ 2. 域名匹配(查询 xy_tenant.domain)
→ 3. 已登录用户 JWT 中的 TenantId
→ 结果注入 context
解析结果为 0 表示平台级请求,不做租户过滤。
中间件链
租户后台接口的中间件执行顺序:
CORS → ResponseHandler → TenantResolve → TenantAdminAuth → DemoGuard → Controller
| 中间件 | 职责 |
|---|---|
| CORS | 跨域处理,允许 X-Tenant-Id 头 |
| ResponseHandler | 统一响应包装 |
| TenantResolve | 解析并注入租户 ID |
| TenantAdminAuth | 租户管理员 JWT 鉴权 |
| DemoGuard | 演示环境保护(可选) |
租户 JWT 认证
租户管理员使用独立的 Token 签发与解析逻辑(token.GenerateTenant / token.ParseTenant),与平台管理员 Token 互不冲突。
租户登录
→ POST /tenant/auth/login
→ 按 username 查询 xy_tenant_admin
→ 校验租户状态与密码
→ 签发 JWT(携带 TenantId + AdminId)
→ 返回 Token
数据库表族一览
| 用途 | 表名 |
|---|---|
| 租户主表 | xy_tenant |
| 租户套餐 | xy_tenant_group |
| 套餐菜单授权 | xy_tenant_group_menu |
| 租户管理员 | xy_tenant_admin |
| 租户角色 | xy_tenant_role |
| 角色菜单 | xy_tenant_role_menu |
| 管理员角色 | xy_tenant_admin_role |
| 租户菜单 | xy_tenant_menu |
| 租户部门 | xy_tenant_dept |
| 租户岗位 | xy_tenant_post |
| 租户配置 | xy_tenant_config |
| 账户流水 | xy_tenant_account_log |