多租户架构

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