Laravel 8 多租户选型需按隔离需求分三级:金融政务选独立数据库,中小客户选共享库独立 Schema,MVP 阶段选共享库 + tenant_id 行级隔离;后者最常用,需加全局作用域、租户中间件、自动填充 trait 及复合索引。

在 Laravel 8 中实现多租户数据库隔离,核心是根据业务安全要求与运维成本,在三种主流模式中选型并落地:独立数据库、共享库独立 Schema、共享库共享 Schema(行级隔离)。没有“唯一正确”的方案,只有更匹配当前阶段的方案。
明确隔离级别需求再选架构
先判断你的 SaaS 项目对数据隔离的硬性要求:
- 金融、政务或大型企业客户为主 → 优先考虑独立数据库(最高隔离,故障影响面小,合规友好)
- 中小客户为主,需平衡成本与隔离性 → 共享数据库 + 独立 Schema(如 PostgreSQL 的 schema 或 MySQL 5.7+ 的 database 切换)
- 早期 MVP、用户量低、快速验证 → 共享数据库 + tenant_id 字段(最轻量,但必须全程强制过滤)
共享库 + tenant_id 行级隔离(最常用)
这是 Laravel 8 项目起步最稳妥的选择,无需额外 DB 权限或复杂连接管理:
- 所有业务表增加 tenant_id INT NOT NULL 字段,并为
(tenant_id, id)或高频查询字段建复合索引 - 定义全局作用域(Global Scope),在模型基类中统一注入租户约束:
protected static function booted() { static::addGlobalScope('tenant', new TenantScope); } - 用中间件识别租户来源(子域名 / 请求头 / 登录态),将租户 ID 存入请求上下文(如
$request->attributes->set('tenant_id', $id)) - 配合 Trait 自动填充新建记录的
tenant_id,避免手动遗漏
独立数据库动态切换(高隔离刚需)
适合租户间数据完全不可见、审计严格或定制化程度高的场景:
- 在
config/database.php中预定义多个连接,或运行时用DB::purge()+DB::extend()动态注册连接 - 中间件中解析租户标识(如子域名
acme.yoursaas.com),查出对应数据库配置,调用Config::set('database.connections.tenant', [...]) - 模型中指定连接:
protected $connection = 'tenant';,或在查询时链式调用on('tenant') - 注意事务跨连接不生效,需确保单次请求只操作一个租户库;登录/认证等系统表仍走主连接
性能与安全必须同步加固
无论选哪种方案,漏掉这些就容易出问题:
-
禁止裸查:禁用
User::all()类操作,全部改用带租户约束的查询;可配合 IDE 插件或静态分析工具拦截 -
索引要带 tenant_id:例如订单按时间查得多,就建
INDEX idx_tenant_created (tenant_id, created_at) -
连接池与超时控制:租户库数量多时,避免连接数爆炸,用 PDO 的
options => [PDO::ATTR_PERSISTENT => false]控制 -
事务隔离级别按需设:在
config/database.php的连接配置里加'isolation_level' => 'READ COMMITTED',防脏读


















