Skip to content

Commit 6f79d23

Browse files
committed
update docs
1 parent 9311aa0 commit 6f79d23

File tree

4 files changed

+108
-1
lines changed

4 files changed

+108
-1
lines changed

docs/.vuepress/_bulletin.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
## 多租户模式
2+
3+
fba 已新增多租户模式适配:
4+
5+
- 开启方式:`TENANT_ENABLED = True`
6+
- 完整能力:安装 [tenant 插件](https://fastapi-practices.github.io/fastapi_best_architecture_docs/marketplace.html)
7+
8+
::: caution
9+
当前为实验性实施,相关适配可参考 [PR #1101](https://github.com/fastapi-practices/fastapi-best-architecture/pull/1101)
10+
:::

docs/.vuepress/bulletin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import path from 'node:path'
55
export const myBulletin: BulletinOptions = {
66
// layout: 'center',
77
border: true,
8-
enablePage: false,
8+
enablePage: true,
99
lifetime: 'session',
1010
title: '公告',
1111
contentFile: path.join(__dirname, '_bulletin.md'),

docs/.vuepress/sidebar.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const mySidebar: ThemeSidebarMulti = {
4747
{ text: '代码生成', link: 'code-generation' },
4848
{ text: '切换主键', link: 'pk' },
4949
{ text: '切换数据库', link: 'db' },
50+
{ text: '多租户', link: 'tenant' },
5051
{ text: 'OAuth 2.0', link: 'oauth2' },
5152
{ text: 'SocketIo', link: 'socketio' },
5253
{ text: 'Celery', link: 'celery' },

docs/backend/reference/tenant.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
title: 多租户
3+
---
4+
5+
fba 已新增多租户模式适配,但==当前主仓库提供的是“多租户运行模式支持”而不是完整的租户业务系统=={.note}
6+
7+
完整租户能力需安装 [tenant 插件](https://github.com/fastapi-practices/tenant),该插件当前提供:
8+
9+
- 租户管理
10+
- 套餐管理
11+
- 行级数据隔离
12+
13+
::: caution
14+
此能力当前仍处于实验性阶段,相关适配来自 [PR #1101](https://github.com/fastapi-practices/fastapi-best-architecture/pull/1101)
15+
:::
16+
17+
## 常见隔离模型
18+
19+
参考 [django-tenants](https://github.com/django-tenants/django-tenants?tab=readme-ov-file#why-schemas)
20+
对多租户的总结,常见方案通常有 3 类:
21+
22+
### 独立式方案
23+
24+
每个租户使用独立数据库,隔离性最强,但运维、迁移、资源管理和成本控制都会更复杂
25+
26+
### 半隔离式方案
27+
28+
所有租户共用一个数据库实例,但每个租户拥有独立 schema。它通常被视为一种折中方案:
29+
30+
- 相比独立数据库,更容易统一运维
31+
- 相比共享 schema,隔离边界更清晰
32+
- 能复用同一数据库连接、缓存和内存资源
33+
34+
### 共享方案
35+
36+
所有租户共用同一套表结构,通常在业务表中增加 `tenant_id` 一类字段,再通过查询条件、约束、上下文和中间件完成隔离
37+
38+
## Schema 方案
39+
40+
`django-tenants` 选择的是“半隔离式方案”,并认为它在简单性与性能之间取得了较好的平衡:
41+
42+
- 只需要维护一个数据库实例
43+
- 对现有业务代码的入侵通常较小
44+
- 租户之间的物理边界比 `tenant_id` 过滤更直观
45+
- 在 PostgreSQL 中可借助 `search_path` 按请求切换到目标 schema
46+
47+
不过,这并不意味此方案一定优于其他方案。它同样有前提和边界,例如更依赖数据库能力、对 PostgreSQL 更友好、跨数据库兼容性也更受限制
48+
49+
## 方案应用
50+
51+
当前 fba 的多租户模式采用“共享方案”,这样做的主要目的是:
52+
53+
- 更容易兼容 PostgreSQL 与 MySQL
54+
- 更容易复用现有模型、插件和初始化 SQL 体系
55+
- 对现有单租户代码的改造路径更平滑
56+
57+
对应地,这种方案也要求开发者更加重视 `tenant_id` 注入、查询过滤、唯一约束和插件兼容性,否则更容易出现越权或串租户风险
58+
59+
## 如何开启
60+
61+
:::: steps
62+
63+
1. 安装 [tenant 插件](https://github.com/fastapi-practices/tenant)
64+
65+
2. 修改 `backend/core/conf.py`
66+
67+
```py
68+
# 租户
69+
TENANT_ENABLED: bool = True
70+
TENANT_DEFAULT_ID: int = 0
71+
```
72+
73+
3. 重新初始化数据库
74+
75+
启用后,部分表会新增 `tenant_id` 字段,部分唯一约束和初始化 SQL 也会变化
76+
77+
::: warning
78+
如果你已经执行过初始化、迁移或已写入正式数据,不应直接在原数据库上切换,建议清空相关表后重新初始化
79+
:::
80+
81+
::::
82+
83+
## 默认租户
84+
85+
`TENANT_DEFAULT_ID` 默认为 `0`,它主要用于:
86+
87+
- 默认租户兜底
88+
- 非授权接口初始化上下文
89+
- 日志记录中的默认租户 ID
90+
- 登录接口未显式传入 `tenant_id` 时的默认值
91+
92+
## 注意事项
93+
94+
- 完整的租户后台、套餐管理、租户状态校验等业务能力由 `tenant` 插件提供,主仓库主要负责基础适配
95+
- 当前实现为共享数据库下的租户模式适配,隔离能力以插件内的行级数据隔离实现为准
96+
- 如果你同时使用 OAuth2、通知公告等插件,请确认对应插件版本已兼容多租户模式

0 commit comments

Comments
 (0)