单Django项目使用MySQL实现多子域名多租户部署的最佳方案是什么
MySQL环境下Django多租户(独立数据库隔离)实现方案
问题核心结论
完全可以实现。你此前了解到的和PostgreSQL强绑定的Django多租户方案,大多是django-tenant-schemas这类依赖PostgreSQL独有的schema特性的实现,这类方案确实无法兼容MySQL。但你需要的是独立数据库级别的租户隔离,和schema隔离属于完全不同的实现路径,MySQL环境完全可以支撑。
推荐实现路径
针对你的标准化SaaS产品、专属子域名、独立数据库的需求,最适配的方案是Django动态数据库路由+子域名解析中间件,实现逻辑如下:
- 第一步:配置公共基础库
在settings.py中先配置一个公共数据库,专门存储租户元数据:包括租户子域名、对应的MySQL数据库连接信息、机构基础配置、账号权限等,这个库不存储任何租户业务数据。 - 第二步:实现子域名解析中间件
自定义Django中间件,在请求进入业务视图前,从request.META['HTTP_HOST']中提取子域名前缀,和公共库中存储的租户子域名做匹配:匹配失败直接返回404或跳转主站;匹配成功后将对应租户的信息存入request.tenant全局对象,同时将该租户对应的数据库配置动态写入Django运行时的DATABASES配置项中。
前置操作:你需要在域名服务商处配置泛解析
*.example.com指向服务IP,新增租户时无需单独做子域名解析配置。
- 第三步:自定义数据库路由
实现Django自定义数据库路由类,根据当前请求携带的request.tenant信息,将所有业务模型的读写操作自动路由到对应租户的独立数据库中,公共库的元数据操作单独路由到公共库。 - 第四步:适配数据迁移逻辑
独立数据库模式下默认的migrate命令只会操作默认数据库,你需要编写自定义迁移脚本,每次产品功能迭代时,批量对所有租户的独立数据库执行迁移操作,保证所有租户的表结构版本完全一致。
备选方案
如果后续租户规模增长到数百级,维护大量独立MySQL数据库的运维成本过高,可以根据需求选择以下方案:
- 共享数据库共享表结构方案:所有租户共用同一个MySQL数据库,所有业务表新增
tenant_id字段,中间件解析子域名获取租户ID后,所有数据库操作自动携带tenant_id过滤条件,实现逻辑隔离。该方案隔离等级低于独立数据库,需要额外做权限校验避免跨租户数据泄露,适合对数据隐私要求不是极端严格的场景。 - 单租户单实例部署方案:如果租户数量极少(小于5个),也可以为每个租户单独部署一套Django实例,每个实例绑定对应子域名和独立数据库,开发成本极低,但迭代、运维成本会随租户数量增长线性上升,不适合大规模使用。
开发注意事项
- 业务模型不要硬编码数据库别名,所有读写操作全部通过数据库路由自动匹配对应库
- 为每个租户的数据库分配独立的MySQL账号,每个账号仅授予对应库的读写权限,从数据库层面进一步加固数据安全
- 敏感操作(如批量数据导出、跨表统计)需要额外做租户权限校验,避免出现越权漏洞
- 做好迁移脚本的版本管理,上线前先在测试租户库验证迁移逻辑,避免出现部分租户库表结构不一致的问题
内容的提问来源于stack exchange,提问作者TechPertz
相关产品推荐
相关产品推荐

