首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >三态组织类型划分:单组织、集团与多租户的隔离边界对比

三态组织类型划分:单组织、集团与多租户的隔离边界对比

原创
作者头像
驰骋工作流程
发布于 2026-10-13 10:15:16
发布于 2026-10-13 10:15:16
300
举报

一篇偏架构视角的对照分析:同一套组织语义,如何通过运行模式配置在三种隔离策略间切换,各自适用的场景、付出的代价,以及从一种形态演进到另一种形态时要做哪些准备。

开篇:为什么要有「三种组织」?

在企业数字化里,组织结构从来不是一张通讯录——它是流程找人、权限隔离、低代码应用分域的共同地基。人员、部门、角色,以及它们之间的对应关系,决定了系统「谁能看见什么、谁能审批什么」。

该 BPM 平台将这套语义持久化在 Port_* 系列数据表中,实体类统一归属 BP.Port 命名空间。五张核心表(Port_Dept、Port_Emp、Port_Station、Port_DeptEmp、Port_DeptEmpStation)撑起全部组织语义;在此基础上,该平台用一个配置项切换三种截然不同的运行世界:

配置值

枚举

俗称

一句话比喻

0

RunModel.Single

单组织版

一个家,一位家长

1

RunModel.GroupInc

集团版

一个生产队,队长管多户人家

2

RunModel.SAAS

多租户版

联合国开大会,各国互不隶属

这不是三套产品,而是同一套引擎、同一套表结构、三种隔离策略——从单机部署到集团管控,再到 SaaS 商业化,改配置即可演进,不必推倒重来。


一、代码里的「总开关」:RunModel

运行模式在源码中定义为枚举 RunModel(BP.Sys.EnumLab):

代码语言:javascript
复制
public enum RunModel
{
    Single,    // 单机版 / 单组织
    GroupInc,  // 集团模式
    SAAS,      // 多租户模式
    PASS       // 平台应用模式(扩展)
}

系统通过 appsettings.json / app.config 中的 RunModel 键读取,逻辑集中在 SystemConfig.RunModel:

配置值

生效模式

0 或 3

单组织(Single)

1

集团(GroupInc)

2

多租户(SAAS)

设计要点:全站数百处业务分支——人员编号规则、管理员判定、数据查询过滤、枚举共享——均读取这一开关。组织隔离不是某个模块的「补丁」,而是贯穿 BP.En30 引擎层的横切能力。


二、组织数据的共同底座:Port_* 与 BP.Port

无论哪种运行模式,组织结构的核心语义不变:

主体

关系

客体

连接键

Port_Org

一对多

Port_Dept

OrgNo

Port_Dept

一对多

Port_Emp

FK_Dept

Port_Dept

一对多

Port_DeptEmp

FK_Dept

Port_Emp

一对多

Port_DeptEmp

FK_Emp

Port_Station

一对多

Port_DeptEmpStation

FK_Station

Port_Dept

一对多

Port_DeptEmpStation

FK_Dept

Port_Emp

一对多

Port_DeptEmpStation

FK_Emp

Port_Org

一对多

Port_OrgAdminer

OrgNo

表名

实体类

职责

Port_Dept

Dept

部门树,ParentNo + OrgNo

Port_Emp

Emp

人员主档,含主部门 FK_Dept

Port_Station

Station

角色(岗位)

Port_DeptEmp

DeptEmp

部门—人员(支持兼职)

Port_DeptEmpStation

DeptEmpStation

部门—角色—人员(流程选人核心)

Port_Org

Org

组织/租户单元

Port_OrgAdminer

—

主管理员与二级管理员

流程引擎「按部门 + 角色找人」的 SQL 直指五表核心:

代码语言:javascript
复制
SELECT FK_Emp FROM Port_DeptEmpStation
WHERE FK_Station = '角色编号' AND FK_Dept = '部门编号'

三种模式共享这套表,差异体现在 OrgNo 怎么用、账号是否全局唯一、数据能否跨组织共享。


三、单组织版:一台服务器,一位 admin

3.1 业务画像

  • 典型场景:中小企业、部门内网、POC 演示、私有化单实例部署。
  • 全系统只有一个逻辑组织,通常由账号 admin 统一管理组织、数据源与流程。
  • 无需 OrgNo 隔离——WebUser.OrgNo 在单组织模式下直接返回空字符串。

3.2 代码印证

组织编号为空(WebUser.cs):

代码语言:javascript
复制
if (BP.Difference.SystemConfig.RunModel == RunModel.Single)
    return "";  // OrgNo 属性

管理员判定:admin / system 账号,或 Port_OrgAdminer 中的二级管理员,或历史 GloVar 标记均可获得管理权限。

人员编号:Emp.UserID 与 Emp.No 等价,无租户前缀:

代码语言:javascript
复制
// SAAS 模式下 UserID 可重复;单组织下 UserID 即 No
if (BP.Difference.SystemConfig.RunModel == RunModel.SAAS)
    return this.GetValStringByKey(EmpAttr.UserID);
return this.GetValStringByKey(EmpAttr.No);

数据查询:枚举、表单、角色等实体不附加 OrgNo 过滤条件,模型最简、集成成本最低。

3.3 一句话总结

单组织版 = 零隔离开销的完整 BPM。适合「我就要一套流程平台」的客户,部署快、学习曲线平。


四、集团版:生产队与多户人家

4.1 业务画像

该平台用「生产队」比喻集团版,形象且准确:

  • 集团管理员 admin:相当于生产队长,可创建多个下属组织。
  • 每个组织一位主管理员(家长):在 Port_Org.Adminer 登记;可配置多位二级管理员(Port_OrgAdminer)。
  • 数据隔离:各部门、流程、表单、角色默认按 OrgNo 隔离,A 组织设计的流程,B 组织默认看不见。
  • 选择性共享:集团模式下,枚举等资源支持 IsShare 标记,可将本组织资产共享给其他组织使用。
  • 账号全局唯一:同一工号在全集团只出现一次(Port_Emp.No 唯一),人员可在组织间调配,符合大型国企、控股集团的 HR 实践。

4.2 代码印证

组织实体(BP.WF.Port.Admin2Group.Org → 表 Port_Org):

代码语言:javascript
复制
Map map = new Map("Port_Org", "独立组织");
map.AddTBString(OrgAttr.Adminer, null, "创始人", ...);  // 主管理员

管理员层级(WebUser.IsAdmin / WebUser.IsAdmin2):

  • IsAdmin:admin 系统账号,或 Port_OrgAdminer 中当前组织的管理员,或 Port_Org.Adminer 主管理员。
  • IsAdmin2:在 Port_OrgAdminer 中但不是 Port_Org.Adminer 主管理员 → 二级协助管理员。

组织上下文注入:集团模式下登录后,WebUser.OrgNo 从 Port_Emp 按人员 No 解析:

代码语言:javascript
复制
string no = DBAccess.RunSQLReturnString(
    "SELECT OrgNo FROM Port_Emp WHERE No='" + WebUser.No + "'");

数据隔离 + 跨组织共享(以枚举为例,MapData.cs):

代码语言:javascript
复制
// 本组织枚举
sqlWhere = " EnumKey IN (...) AND OrgNo='" + orgNo + "'";
// 集团共享:其他组织 IsShare=1 的枚举 UNION 进来
if (RunModel == RunModel.GroupInc) {
    sqlEnum += " UNION SELECT A.* FROM ... AND B.IsShare=1 AND B.OrgNo!='" + WebUser.OrgNo + "'";
}

Sys_EnumMain 在集团模式下显式提供共享开关:

代码语言:javascript
复制
if (SystemConfig.RunModel == RunModel.GroupInc)
    map.AddBoolean("IsShare", true, "是否共享给其他组织?", true, true);

角色体系可按组织定制(Station.cs):GroupStationModel 支持「每组织独立岗责」或「每部门独立岗责」,适应不同集团管控粒度。

4.3 一句话总结

集团版 = 统一身份 + 分权治理 + 可选共享。一个账号走天下,各子公司流程自治,集团资产可下沉复用。


五、SAAS 多租户版:联合国与各小国

5.1 业务画像

  • 超级管理员 admin:平台运营方,负责开通租户(组织)。
  • 每个租户一位管理员,可设多位二级管理员——与集团版表面相似,但本质不同:
    • 租户之间无业务往来、无隶属关系,彼此完全隔离。
    • 用户账号租户内唯一、跨租户可重复:租户 A 的 001 与租户 B 的 001 是两个人。
    • 物理上可同库同表,逻辑上靠 OrgNo + 编号前缀实现硬隔离。

5.2 代码印证

账号双字段设计(Emp.cs):

字段

含义

UserID

租户内登录名,可重复

No

全局主键,格式 OrgNo_UserID

代码语言:javascript
复制
/// 用户ID: SAAS模式下 UserID 是可以重复的.
if (RunModel == RunModel.SAAS) {
    if (!value.StartsWith(WebUser.OrgNo + "_"))
        this.SetValByKey(EmpAttr.No, WebUser.OrgNo + "_" + value);
}

对外暴露的统一用户标识(WebUser.UserID):

代码语言:javascript
复制
if (SystemConfig.RunModel == RunModel.SAAS)
    return WebUser.OrgNo + "_" + WebUser.No;  // 全局唯一
return WebUser.No;

组织解析按 UserID(与集团版按 No 不同):

代码语言:javascript
复制
// SAAS:按 UserID 查 OrgNo
"SELECT OrgNo FROM Port_Emp WHERE UserID='" + WebUser.No + "'"

部门人员关系带 OrgNo(DeptEmp.cs):SAAS 模式下 Port_DeptEmp 查询附加 OrgNo 条件,防止跨租户兼职数据串读。

SQL 构建层适配(SqlBuilder.cs):关联 Port_Emp 时,SAAS 模式自动将外键字段映射为 UserID,保证报表与实体查询在租户语义下正确。

枚举主键租户化(SysEnumMain 设计注释):

代码语言:javascript
复制
// 如果是 SAAS 模式, No = OrgNo + "_" + EnumKey

5.3 一句话总结

SAAS 版 = 强隔离的小国家模型。平台方一套部署服务千企,租户账号可「重名」,引擎用 OrgNo_ 前缀保证全局不碰撞。


六、三态对比总览

维度

单组织 Single

集团 GroupInc

SAAS 多租户

配置值

0

1

2

顶层管理员

admin

集团 admin

平台 admin

组织单元

无(逻辑单组织)

Port_Org,可多级

Port_Org 租户

OrgNo 作用

不使用(空)

核心隔离键

核心隔离键

人员 No 唯一性

全局唯一

全局唯一

OrgNo_UserID 全局唯一

UserID 可重复

否(等同 No)

否

是(租户内唯一即可)

跨组织数据共享

不适用

支持(如 IsShare)

不支持

组织间关系

—

可有层级/隶属

平级、互不往来

典型客户

中小企业、内网

国企集团、控股公司

ISV、云 BPM 平台

比喻

一家一户

生产队 + 多户人家

联合国 + 各国

运行模式

顶层管理员

组织单元

组织间关系

单组织 Single

admin

无(逻辑单组织)

不适用

集团 GroupInc

集团 admin

Port_Org(可多级)

可有层级隶属,IsShare 可选共享

多租户 SAAS

平台 admin

Port_Org 租户

平级,互不隶属、互不往来


七、与流行设计的对比

7.1 业界常见三种多组织方案

方案

代表思路

典型实现

A. 独立库/独立 Schema

每租户一个数据库

阿里云 RDS 多库、部分 OA

B. 共享库 + 行级 tenant_id

所有表加租户列

Salesforce、多数 SaaS ORM

C. 共享库 + 逻辑组织树

一棵大树,节点即组织

用友 NC、部分 ERP

7.2 该平台方案的定位

该平台走的是 「B + C 混合」 路线:

  • 共享库、共享核心表(五表 + OrgNo),部署与运维成本低于独立库方案;
  • 集团版在 B 的基础上增加 组织树 + 共享标记(C 的变体),满足「总部统管、分子公司自治」;
  • SAAS 版在 B 的基础上增加 OrgNo_ 编号前缀,解决「租户内账号可重名」的商用刚需。

7.3 对比矩阵

评价维度

独立库/Schema

纯 tenant_id 行隔离

该平台三态方案

租户强隔离

★★★★★

★★★

★★★★(SAAS 前缀 + OrgNo 双保险)

部署运维成本

★★

★★★★★

★★★★★(单库单实例)

集团内资源共享

★★

★★★

★★★★(IsShare 等显式机制)

从单组织平滑升级

★

★★★

★★★★★(改配置 + 补 OrgNo)

集成 HR 主数据

★★★

★★★★

★★★★(五表与编制语义对齐)

防串租户工程纪律

物理隔离

依赖每 SQL 带条件

引擎层 WebUser.OrgNo + 实体 Hidden 条件

跨租户账号重名

天然支持

需额外设计

原生支持(SAAS UserID)


八、这样设计的优点

8.1 一套代码,三种商业形态

从私有化单机到集团管控再到云端 SaaS,无需 fork 代码分支。RunModel 一处配置,人员实体、管理员逻辑、枚举查询、SQL 构建器同步切换——显著降低产品线的研发与测试矩阵。

8.2 组织语义不随模式而变

五表核心模型在三种模式下保持一致,流程选人规则、部门树、兼职与角色绑定不因升级模式而失效。实施顾问学会一套组织建模方法,即可服务不同规模客户。

8.3 隔离策略与业务场景精准匹配

  • 单组织:零开销,最快上线;
  • 集团:全局账号 + 分权 + 可选共享,贴合国企治理;
  • SAAS:租户账号可重名,降低中小企业上云门槛(001、admin 无需加随机后缀)。

8.4 引擎层强制隔离,而非靠自觉

集团/SAAS 模式下,Emp、Station、DeptEmp 等实体的 EnMap 自动注入:

代码语言:javascript
复制
if (RunModel != RunModel.Single)
    map.AddHidden("OrgNo", "=", "@WebUser.OrgNo");

列表查询、表单维护默认带组织过滤,减少「忘写 WHERE OrgNo」导致的数据穿透。

8.5 管理员模型清晰可落地

Port_Org.Adminer(主管理员)+ Port_OrgAdminer(含二级)+ 系统 admin,三级权限边界在 WebUser.IsAdmin / IsAdmin2 中集中实现,便于审计与权责划分。


九、这样设计的局限与应对

局限

说明

应对建议

共享库架构的上限

超大规模租户(万级以上)单库压力需分库分表

按 OrgNo 水平拆分;只读副本;冷热数据归档

引擎分支散布

RunModel 判断分布在多文件

新功能优先走 WebUser.OrgNo 与实体 Hidden 约定;避免重复造隔离逻辑

集团 vs SAAS 概念相近

实施顾问可能混淆

牢记:集团 = 账号全局唯一 + 可共享;SAAS = 账号可重名 + 绝不共享

SAAS 编号前缀

外部系统集成时需传递完整 No

使用 WebUser.UserID(已含 OrgNo_)作为对外主键;文档明确映射规则

单组织迁移

升级到集团需补录 OrgNo、创建 Port_Org

提供 OrganizationAPI 同步接口与数据初始化工具

纯行隔离非物理隔离

金融等强合规场景可能要求独立库

支持按租户导出/独立部署实例;敏感客户可采用「一租户一实例」托管


十、选型指南:我该怎么选?

代码语言:javascript
复制
                    ┌─────────────────────────────────────┐
                    │         需要 BPM 平台?              │
                    └─────────────────┬───────────────────┘
                                      │
              ┌───────────────────────┼───────────────────────┐
              │                       │                       │
        仅一个法人实体            多法人/多子公司            对外售卖云服务
        无组织隔离诉求            同一套 HR 主数据           租户互不感知
              │                       │                       │
              ▼                       ▼                       ▼
      RunModel=0           RunModel=1         RunModel=2
         单组织版                   集团版                  SAAS 版

如果你……

推荐模式

500 人以下企业,一套流程走天下

单组织

央企/集团,各子公司自建流程但账号统一

集团

软件公司做 BPM 云平台,客户自助开通

SAAS

先从单组织起步,未来可能集团化

单组织 → 集团(补 OrgNo,改配置)

已集团化,要对外 SaaS 化

评估账号模型差异,规划 UserID 与编号迁移


十一、结语:一种架构哲学

该 BPM 平台的组织类型划分,体现的不仅是技术选型,更是一种务实的企业软件哲学:

不为一棵树砍整片森林——五表撑起全部组织语义; 不为一种客户造一个产品——一个 RunModel 切换三种商业世界; 不让流程引擎绕过组织——OrgNo 从登录态渗透到查询、枚举、角色与管理员判定。

从单组织的「一位 admin」,到集团版的「队长与家长」,再到 SAAS 的「联合国与各小国」——该平台用同一套 Port_* 底座,把组织结构做成了可生长、可商业化、可集成的平台能力。

这正是该平台 BP 架构在 4.3 节所要传达的核心:组织类型不是表多表少的问题,而是隔离边界与商业形态是否匹配的问题。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 开篇:为什么要有「三种组织」?
  • 一、代码里的「总开关」:RunModel
  • 二、组织数据的共同底座:Port_* 与 BP.Port
  • 三、单组织版:一台服务器,一位 admin
    • 3.1 业务画像
    • 3.2 代码印证
    • 3.3 一句话总结
  • 四、集团版:生产队与多户人家
    • 4.1 业务画像
    • 4.2 代码印证
    • 4.3 一句话总结
  • 五、SAAS 多租户版:联合国与各小国
    • 5.1 业务画像
    • 5.2 代码印证
    • 5.3 一句话总结
  • 六、三态对比总览
  • 七、与流行设计的对比
    • 7.1 业界常见三种多组织方案
    • 7.2 该平台方案的定位
    • 7.3 对比矩阵
  • 八、这样设计的优点
    • 8.1 一套代码,三种商业形态
    • 8.2 组织语义不随模式而变
    • 8.3 隔离策略与业务场景精准匹配
    • 8.4 引擎层强制隔离,而非靠自觉
    • 8.5 管理员模型清晰可落地
  • 九、这样设计的局限与应对
  • 十、选型指南:我该怎么选?
  • 十一、结语:一种架构哲学
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档