所有权与生命周期
另有 28 种语言版本
English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

第 8 个模块,共 10 个,属于 Data Architect 课程第 3 章Salesforce 数据架构。每个模块都可以单独阅读。 上一篇:关系会带来后果 · 下一篇:保持数据一致
**本模块回答的问题:**谁拥有这条记录,它在整个生命周期中会经历什么?
看一个数据模型时,我不只想知道有哪些对象以及它们如何连接。我想知道记录随着时间推移会经历什么。谁创建它们?谁拥有它们?谁可以重新分配它们?当业务关系变化、它们不再活跃时会怎样?它们应该被删除吗,我们要保留多久?这些都不会出现在 ERD 上,也就是实体关系图:第 2 章数据模型里的那些方框和连线。但这些全都是数据架构。而在 Salesforce 上,所有权正是数据模型和安全模型迎头相撞的地方。
所有权不只是字段里的一个名字
Section titled “所有权不只是字段里的一个名字 ”管理员在记录上看到所有人,会把它当作一个标签来读:Bart 拥有这个客户,Lisa 拥有那个个案。它可以是这个意思。但在 Salesforce 上,所有权也是一种平台机制。在有所有人的对象上,所有人决定了谁能通过角色层级、共享规则、队列和重新分配看到这条记录。所以当我问“谁拥有这条记录?”时,我不是在问页面上写谁的名字。我是在问我们给它附加了什么样的安全和生命周期行为。所有人可以是一个用户,对于某些对象(其中包括自定义对象、个案和潜在客户)也可以是一个队列,无论哪种,所有人都对这条记录拥有完全访问权限(Understanding Sharing (opens in a new tab),英文)。
这就是为什么我把业务责任和记录所有权分开。有时它们是同一个人,有时不是。如果业务说一位调度员对一次配送负责,这并不自动让调度员成为所有人。责任可以放在它自己的字段里,而所有权则设置成能支撑安全和规模的样子。不要只因为两者都用了“所有者”这个词就把它们混为一谈。
共享表:所有权在这里变成访问权限
Section titled “共享表:所有权在这里变成访问权限 ”有些人甚至不知道共享表是什么。每个数据架构师都应该知道。
一条记录的大部分共享信息都保存在一个相关的共享对象里,这是 Salesforce 版本的访问控制列表(Understanding Sharing (opens in a new tab),英文)。Account 有 AccountShare,Contact 有 ContactShare,自定义对象也有自己的共享对象:Truck__c 有 Truck__Share(Sharing a Record Using Apex (opens in a new tab),英文)。其中每一行说明四件事:
- 哪条记录:父记录 ID。
- 谁:一个用户,或者一个组(公用组、某个角色的组、一个区域)。
- 多少权限:读取、编辑,或者全部(完全访问)。
- 为什么:行原因(Row Cause)。所有人对应
Owner,共享规则对应Rule,手动共享对应Manual,还有Team、Salesforce 在客户与其子记录之间添加的隐式原因,以及开发人员为 Apex 共享定义的原因。
在课上,我一边共享一条记录,一边打开 Workbench 查询共享表,你会看着行出现又消失。当有人问“为什么这个人能看到那个?”时,答案往往就躺在某一行里,连同它的原因。
但并不是所有东西都在里面。组织范围默认设置不是一行。角色层级也不存储在那里:所有人上级那些人的访问权限是在需要时才计算出来的。而“查看所有”、“修改所有”、“查看所有数据”和“修改所有数据”则完全跳过共享表(Sharing a Record Using Apex (opens in a new tab),英文)。正如我在课上说的:勾选“查看所有”,你就绕过了共享表。
Salesforce 还会因为记录之间的关联而替你共享一些记录。这就是隐式共享,它作用于客户与其子记录之间。如果你能看到一个联系人、个案或业务机会,你也能读取它所属的客户。而客户所有人可以访问该客户的联系人、个案和业务机会,访问级别由所有人的角色设定(Implicit Sharing (opens in a new tab),英文)。在最近的版本中,Salesforce 会在需要时才计算其中一部分子记录访问权限,而不是把它存储为行,所以查询共享表时看不到它,也不必惊讶。这里我只给你一个提示;细节在 Relationships and Built-In Sharing(英文)里。
还有一个例外,适用于你有大量外部用户的情况。高容量社区用户,也就是为成千上万乃至数百万客户设计的 Customer Community 许可证,没有角色,不能加入公用组,也不能通过共享规则或手动共享获得记录(About High-Volume Community or Site Users (opens in a new tab);Sharing Rule Considerations (opens in a new tab),英文)。对他们来说,共享表不是答案:他们通过共享集访问记录,共享集把一条记录的客户或联系人与用户自己的客户或联系人相匹配。这正是这些许可证能够扩展的原因之一。Sharing and Visibility 课程在 Sharing with External Users(英文)里讲到它。
还要记住模块 7:从对象根本没有共享对象。它的访问权限来自主对象的共享对象,以及主从关系字段上的共享设置。
数据架构师为什么要关心?因为所有权就写在这张表里。每一次更换所有人,每一条新的共享规则,每一个用户在角色或组之间的移动,都意味着 Salesforce 要添加和删除行。几千条记录时没人会注意到。到了一千万条,而且大部分归一个用户所有时,就是我们马上要遇到的重新计算。
考点。自定义对象的共享对象命名为
Object__Share,比如Truck__Share。从对象没有共享对象:它的访问权限来自主对象。而当一条记录的所有人发生变化时,它的手动共享会被删除,而带有开发人员自定义原因的 Apex 共享会保留下来。
数据模型在这里把接力棒交给安全模型,其余的我在 Sharing and Visibility Architect 课程中讲:Steve’s 22 Ways to Share a Record(英文)、Org-Wide Defaults, Ownership, Queues and the Role Hierarchy(英文)、讲隐式共享的 Relationships and Built-In Sharing(英文),以及讲 Apex 共享原因的 Programmatic Sharing and Secure Code(英文)。在本课程中,第 12 章会针对人、应用程序和智能体把这些串起来。
有时所有权是继承来的
Section titled “有时所有权是继承来的 ”在上一个模块里我们看到,主从关系中的子记录没有自己的所有人;它跟随父记录。这往往完全正确。业务需要给一次配送上的每个项目各设一个不同的所有人吗?不需要。配送拥有生命周期,项目属于它。这就是为什么关系设计和所有权设计要一起做:当你选择了主从关系时,你就已经做出了所有权决定的一部分。
系统创建的记录归谁所有?
Section titled “系统创建的记录归谁所有? ”事情从这里开始变得有趣。一个人创建了一个客户,也许他就成了所有人。但一个 ERP 一夜之间发来了 10 万笔交易。它们归谁所有?集成用户?一个队列?根据数据推算出的区域所有人?一个五年没人想起过的系统账户?而现在智能体也会创建记录。
我的立场是:**这取决于所有权对共享是否重要。**集成用户或智能体用户是一个有效的用户,它可以拥有记录。如果在这个对象中,所有权决定访问权限(通过角色层级或共享规则),就把记录分配给合适的所有人:一个真实的用户、一个队列,或者一个专门的所有人用户。如果不决定访问权限,保留系统用户作为所有人可能是更好的选择,因为这样审计轨迹就能直接追溯到创建这条记录的东西。
不管怎样,都要有意识地决定。一个拥有所有东西的集成账户,已经悄悄地成了你安全架构的一部分,总得有人知道它一旦被停用会发生什么。
所有权可能变成规模问题
Section titled “所有权可能变成规模问题 ”分布也很重要。一千万条记录分散在几千个所有人名下是一种形状。一千万条记录归一个用户所有,则是截然不同的另一种。当单个用户拥有某个对象超过 10,000 条记录时,Salesforce 把它叫作所有权数据倾斜(Ownership Data Skew (opens in a new tab),英文)。它通常发生在有人把所有东西都停放在一个用户或队列上时:所有未分配的潜在客户都放在一个占位用户名下,每条集成记录都归集成用户所有。在那个用户在角色层级中移动,或者进出某个共享规则所依赖的组之前,它都是无害的。然后 Salesforce 就得调整海量的共享条目,你会遇到长时间运行的重新计算。
相关建议很实用。在可能的情况下,把所有权分散到更多用户身上。如果一个用户必须拥有大量记录,就让他不在角色层级中;如果他需要一个角色,就把他放在顶部一个单独的角色里,并且不要移动他,同时让他不进入共享规则所用的公用组(Ownership Data Skew (opens in a new tab),英文)。同样的思路也适用于上一个模块里那个子记录太多的父记录,即父子数据倾斜。
所以分布是物理模型的一部分。不要只问有多少条记录;要问它们是如何分布的。这是“零的个数”的另一个版本:不只是有几个零,还有零集中在哪里。第 2 部分会深入讨论数据倾斜;在这里,我希望你能预见它的到来。Sharing and Visibility 课程会在 Sharing at Scale(英文)中再次讨论它。
“默认所有人”变成了架构
Section titled ““默认所有人”变成了架构 ”有一个模式我总能看到。没人知道某样东西该归谁所有,于是有人说:“全都分配给集成用户吧”,或者“建一个叫 System 的通用用户”。也许这是对的。但不要在无意中这样做。一个临时的默认值有变成永久的习惯:两年后,每条记录都属于 integration@company.com,没人记得为什么,而改变它成了一个项目。这就是第 1 章的可逆性测试:在把一百万条记录交给一个所有人之前,问一问以后要改变它需要付出什么。
重新分配是一个生命周期事件
Section titled “重新分配是一个生命周期事件 ”所有人会变。销售代表离职,区域调整,团队重组,地区重新划分。有什么依赖于所有人:共享、自动化、报表、队列、升级、集成?如果更换所有人会改变谁能看到这条记录,那么重新分配就不是管理员的清理工作。**它是一个安全事件,**而在一百万条记录的规模下,它也是一个运维事件。发生时留意共享表:所有人变化时,手动共享会被删除,而带有开发人员自定义原因的 Apex 共享会在变化后保留下来(Understanding Sharing (opens in a new tab),英文)。在课上,我把一条记录共享给某人,然后更换所有人,那个人就失去了访问权限。全场每次都很惊讶。
还要记住,所有权不等于访问权限。所有人并不是唯一需要看到一条记录的人,而 Salesforce 有很多授予访问权限的方式:角色层级、共享规则、团队、区域、手动共享和程序化共享。Sharing and Visibility 课程会深入讨论这些,从 Steve’s 22 Ways to Share a Record(英文)开始。架构师的要点更简单:**不要用所有权来解决每一个访问问题。**如果你只是为了让某人能看到一条记录而在调换所有人,你多半是在解决错误的问题。
创建只是开始
Section titled “创建只是开始 ”很多数据建模止步于创建:字段、对象、关系,完事。但这条记录可能会存在十年。它会被更新,更换所有人,改变状态和关系,变为不活跃,成为历史,可能需要归档,有一天也许还要被删除。架构不只是记录如何诞生,而是从诞生到消亡之间发生的一切。
不要只因为东西旧了就删除
Section titled “不要只因为东西旧了就删除 ”一个零售合作伙伴不再派活了。删除这个客户?不会自动删除:它的配送、索赔和计费历史仍然重要。一辆卡车退役了。把它连同它的配送历史和货损索赔一起删除?这样东西也许不再活跃,但它的数据仍然有用。所以我把不活跃和消失分开。一辆退役的卡车可以留在模型里;一位前员工仍然可以出现在审计历史中。架构必须在运营关系结束之后,保留那些重要的事实。
保留是一项业务需求
Section titled “保留是一项业务需求 ”另一面是:永远保留所有东西也不是架构。存储会增长,报表会变慢,搜索会更嘈杂,而隐私法可能规定有些数据必须删除。所以我想要一个明确的答案:这个我们要保留多久?“Salesforce 会保留它”不是保留策略。
而这主要是一个关于交易数据的问题。参考数据,比如产品、服务类型、配送中心,不会变得很庞大,而且有其他记录指向它,所以它通常会留下来。客户数据介于两者之间:也许有一天你会让一个客户退役,尤其是当你持有个人数据而保留它的理由已不复存在时。但数据量在交易里:配送、订单、个案、预约,每天都在创建,永无止境。那才是会增长到几亿行的东西,也正是保留必须明确的地方:也许运营数据在 org 里保留两年,财务记录在某个地方保留七年,某些照片保留九十天。这些都是业务规则,如果没人问过,架构师就应该去问。
我在课上说了很多年:如果你今天不归档,你还会有归档的那一天吗?“以后再说”往往会在三亿条记录时变成一个紧急项目。第 2 部分有一整个模块讲归档和清除,就建立在同一个问题之上。
Steve Trucking:一次配送归谁所有?
Section titled “Steve Trucking:一次配送归谁所有? ”一次配送由集成根据零售合作伙伴的装货清单创建,每天大约 3,300 次。它归谁所有?不是零售合作伙伴;那是一个业务关系。不是收货人。配送小组执行它,但每次配送小组换卡车时,记录都应该更换所有人吗?调度员?配送中心?一个队列?创建它的集成用户?
现在运用本模块,从决定它的那个问题开始:**所有权是否决定了某人对配送的访问权限?**在 Steve Trucking,答案是否定的。调度员看到的是他们配送中心的配送,配送小组看到的是他们路线上的配送,每个零售商在合作伙伴门户中看到自己的配送。这些都不取决于谁拥有这条记录;它们来自配送中心、路线和合作伙伴。
所以我的答案是:**集成用户拥有这些配送。**这是一个系统用户有意拥有记录的好例子:
- **审计轨迹是诚实的。**每次配送的所有人都说明了它的来源:装货清单集成。
- **访问权限来自共享,而不是所有权。**基于配送中心的条件共享规则让每个配送中心的团队看到自己的配送;合作伙伴通过门户访问他们的配送。
- 倾斜已在设计中化解。每天 3,300 次,集成用户三天就会拥有超过 10,000 次配送,所以从第一天起就是所有权数据倾斜,只要我们提前规划,这就没问题。集成用户没有角色,所以层级中它上方没有任何东西需要重新计算,而且它不加入我们共享规则所用的公用组。
- **没人重新分配配送。**配送小组换卡车,调度员换班,而所有人从不改变,所以不会有重新分配风暴,也没有会丢失的手动共享。
还要写下如果这个用户哪天被停用或被替换会发生什么,因为它现在拥有几百万条记录。这正是下一个团队需要找到的那个决定。
**考试之外:AI 改变了什么。**智能体以机器的速度创建和修改记录。如果一个智能体以它自己的用户身份创建了 10 万条记录,“以后再改所有人”就会变成数据倾斜、共享重新计算和一个清理项目。在智能体上线之前就决定它的所有权规则,用的是同一个问题:在这里,所有权对共享重要吗?
架构师在这里决定什么
Section titled “架构师在这里决定什么 ”- 所有权代表的是业务责任、安全机制,还是两者兼有,以及如果责任不放在所有人字段里,它放在哪里。
- 记录需要自己的所有人,还是应该从父记录继承。
- 集成和智能体创建的记录归谁所有,取决于所有权是否决定共享。
- 所有权如何分布,以及当一个用户必须拥有大量记录时如何避免所有权数据倾斜。
- 记录何时变为不活跃,何时归档,保留多久,以及何时删除才是正确的。
看一个物理模型时,不要只问数据存放在哪里。要问**今天谁拥有它,明天谁可能拥有它,以及当我们不再需要它时会怎样。**接下来:即使有了正确的对象、字段、关系和所有人,数据仍然必须保持可信。
- Apex Developer Guide,Understanding Sharing (opens in a new tab)(英文),查阅日期 2026-10-13:所有人(一个用户,或者对于自定义对象、个案和潜在客户来说,一个队列)拥有完全访问权限;大部分共享存放在一个相关的共享对象里;角色层级在运行时推导;所有人变化时手动共享会被删除,Apex 托管共享会保留;行原因的取值。
- Apex Developer Guide,Sharing a Record Using Apex (opens in a new tab)(英文),查阅日期 2026-10-13:
AccountShare、MyCustomObject__Share;从对象没有共享对象;共享对象不记录的内容(组织范围默认设置、角色层级、“查看所有”和“修改所有”)。 - Salesforce Help,Implicit Sharing (opens in a new tab)(英文),查阅日期 2026-10-13:客户与其联系人、个案和业务机会之间的访问权限。
- Salesforce Help,About High-Volume Community or Site Users (opens in a new tab) 和 Sharing Rule Considerations (opens in a new tab)(英文),查阅日期 2026-10-13:没有角色,没有共享规则或手动共享;改用共享集。
- Sharing and Visibility Architect 课程:Steve’s 22 Ways to Share a Record、Org-Wide Defaults, Ownership, Queues and the Role Hierarchy、Relationships and Built-In Sharing、Programmatic Sharing and Secure Code、Sharing with External Users、Sharing at Scale(英文)。
- Salesforce Developers,Designing Record Access for Enterprise Scale,Ownership Data Skew (opens in a new tab) 和 Parent-Child Data Skew (opens in a new tab)(英文),查阅日期 2026-10-02。
