多租户城市站的数据模型:一家企业和它的几十个分站怎么存
tenants / sites / regions 三层怎么分,独立域名、子域名、路径、查询串四种寻址模式怎么统一到一行配置,slug-hash 为什么比自增 ID 好。
三层结构
核心只有三类实体:tenants(企业租户,一牌一家)、city_sites(城市分站,绑定一个地区节点)、regions(省市区树,平台共建共享)。站点不存模板,模板挂在租户上;地区不存文案,文案由站点自己的产品、文章和地区词拼出来。
分站地址没有用裸地区名,而是 slug + 短 hash:kunming-336ec45550 这种。好处是「地区词 + 企业关键词」就算在平台上撞了,hash 也能兜底,而且地址几乎不可能被枚举撞库。
一条解析链管四种接入方式
所有入口(首页、门户、博客)第一步都先走同一个分发:独立域名查 tenant_domains → 子域名查 sites.slug → 路径 /s/{sub}/ 兜底 → 最后才是平台自身。命中城市站就交给 Geo 渲染,命中平台域名才走博客 / 门户。
- 每家租户可以配独立域名或使用平台泛域名,一个字段切换;
- 全站链接形态由 env 一行控制,本地 path、线上 subdomain,代码零改动;
- 解析不到的陌生域名统一 404,不给垃圾域名当镜像的机会。
SQLite 下的唯一约束
踩过的坑: tenants.root_domain 起初允许多租户共用同一个值,但 SQLite 转 schema 后唯一约束生效再插就炸。这类约束要设计时就写进去——租户的对外根域名天然应该唯一,晚了只会变成数据修复。
整套模型在 SQLite 单文件库里十来张表,管理起来很直观:改一列、查一个租户的数据量,一个 SQL 就能看清楚。