Laravel 中的共享数据库多租户架构:基础层

发布日期:2026-07-28 10:00:37  浏览量 :0
发布日期:2026-07-28 10:00:37  
0

太长不看版(TL;DR)

  • 共享数据库多租户架构 = 一个数据库,每一行都带有 tenant_id 标签,并通过全局作用域自动过滤。
  • 三个核心组件:一个 TenantContext 单例、一个 BelongsToTenant 特性(Trait),以及复合唯一约束。
  • 真正的安全保障并非依靠自律,而是一项持续集成测试:当某个包含 tenant_id 的数据表忘记应用该特性(或反之)时,测试将失败。

本周我发布了共享数据库多租户架构的基础层。不涉及路由,也不涉及解析器——只关注让“一行数据归属于一个组织”这一规则成为事实且难以出错的部分。以下是其整体结构。

为何选择共享数据库

主要有三种策略。简要权衡如下:

策略 隔离性 运维成本 适用场景
每租户独立数据库 最强 最高(迁移次数 × N) 租户数量少且规模大,合规要求严格
每租户独立模式(Schema) 中等 使用 PostgreSQL,租户数量适中
共享数据库 + tenant_id 最弱 最低 租户众多,单一代码库,一次性执行迁移

对于许多组织共享同一代码库的全新应用而言,共享数据库在简单性上胜出。但需要注意的是,隔离现在成了的责任,需要在应用程序代码中强制执行。如果漏掉一个 where tenant_id = ? 条件,一个组织就能看到另一个组织的数据。因此,整个设计的核心在于让这种遗漏变得不可能发生。

上下文对象

所有组件都从同一个单例中读取当前租户信息,而不是从请求、会话或全局变量中获取。这使得解析器可以灵活替换——无论是基于配置的本地部署,还是基于域名的软件即服务(SaaS)模式——而无需修改下游的任何代码。

class TenantContext
{
    private ?Tenant $tenant = null;
    private bool $scopeDisabled = false;

    public function id(): ?int { return $this->tenant?->getKey(); }
    public function has(): bool { return $this->tenant instanceof Tenant; }

    public function shouldScope(): bool
    {
        return ! $this->scopeDisabled && $this->has();
    }

    

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

分享到:

长按或扫码识别 分享给好友

长按或扫码识别 分享给好友
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据