WEBKT

Salesforce配置存储对决 Custom Settings与Custom Metadata Types场景选择深度解析

58 0 0 0

核心概念解析

Custom Settings(自定义设置)

Custom Metadata Types(自定义元数据类型 - CMDT)

关键差异深度对比

决策框架:何时选择哪一个?

高级考量与实践建议

总结

在Salesforce平台上构建复杂应用时,如何高效、可靠地管理配置信息至关重要。这些配置可能包括API端点、功能开关、映射值、业务规则参数等等。Salesforce为此提供了几种机制,其中最常用的是Custom Settings(自定义设置)和Custom Metadata Types(自定义元数据类型,简称CMDT)。

虽然它们都能存储数据,但其底层机制、部署方式、访问模式和适用场景却大相径庭。对于架构师和高级开发者来说,理解这些差异并做出明智的选择,直接影响到应用的可维护性、可部署性和性能。你是不是也曾在List Custom Setting、Hierarchy Custom Setting和CMDT之间犹豫不决?别担心,这篇文章将深入剖析这三者的核心区别和最佳实践,帮你彻底搞清楚何时该用哪个。

核心概念解析

在深入比较之前,我们先快速回顾一下这三个工具的基本概念。

Custom Settings(自定义设置)

自定义设置本质上更像是数据,虽然它们提供了一些优于自定义对象存储配置的优势。它们允许你创建自定义的数据集,并能在Apex、公式字段、验证规则、Flow等地方快速访问,关键在于访问它们不计入SOQL查询限制,因为Salesforce会将这些设置缓存起来。

Custom Settings主要有两种类型:

  1. List Custom Settings(列表自定义设置)

    • 结构: 提供一组静态数据,类似于一个没有记录类型、只有组织级别访问权限的自定义对象。每条设置记录有唯一的名称字段(Name)和自定义字段。
    • 用途: 存储组织级别的、不经常变动的列表数据。例如,国家代码与国家名称的映射、产品分类代码等。
    • 访问: 主要通过Apex的CustomSettingName__c.getAll()返回Map<String, CustomSettingName__c>,或CustomSettingName__c.getInstance(dataSetName)获取特定记录。
    • 特点: 数据是全局共享的,没有用户或简档级别的区分。
  2. Hierarchy Custom Settings(层级自定义设置)

    • 结构: 具有内置的层级逻辑,允许你为特定用户、特定简档(Profile)或整个组织定义不同的设置值。Salesforce会根据当前用户的上下文自动查找最具体的设置。
    • 层级顺序: Salesforce查找设置值的顺序是:当前用户 -> 用户简档 -> 组织默认值。找到第一个匹配项即返回。
    • 用途: 实现基于用户或角色的个性化配置。例如,为特定用户或部门开启某个Beta功能、设置不同的API调用次数限制、控制特定用户群体的UI元素可见性等。
    • 访问: 主要通过Apex的CustomSettingName__c.getInstance()(自动根据上下文获取)、CustomSettingName__c.getOrgDefaults()CustomSettingName__c.getInstance(userId)CustomSettingName__c.getInstance(profileId)
    • 特点: 强大的层级覆盖能力,但数据仍然是数据。

Custom Metadata Types(自定义元数据类型 - CMDT)

CMDT是Salesforce推荐的现代应用配置管理方式。与Custom Settings最大的不同在于,CMDT被视为元数据(Metadata),而不是数据。

  • 结构: 类似于自定义对象,可以定义自定义字段(包括关系字段、选项列表、复选框等,比Custom Settings支持的类型更丰富)。每条记录有Label和Developer Name。
  • 用途: 存储应用程序的核心配置信息,这些信息通常与代码一起打包和部署。例如,集成服务的端点URL和认证信息、复杂的业务规则定义、动态页面布局的配置、映射表等。
  • 访问: 可以通过SOQL直接查询,并且读取操作不计入SOQL查询限制!也可以通过Apex的getAll()getInstance(recordId)getInstance(developerName)方法访问。
  • 特点:
    • 可部署: 作为元数据,CMDT记录可以通过变更集(Change Sets)、Metadata API、SFDX等工具在不同环境(沙箱、生产)之间轻松部署,无需手动导入数据或运行脚本。
    • 治理性强: 元数据天然支持版本控制和更严格的部署流程。
    • 关系字段: 可以创建指向其他CMDT或标准/自定义对象的元数据关系字段,构建更复杂的配置结构。
    • 包容性: 可以包含在托管或非托管包中。

关键差异深度对比

理解了基本概念后,让我们把这三者放在一起,进行一次全方位的对比。这部分是决策的关键。

特性 List Custom Setting Hierarchy Custom Setting Custom Metadata Type (CMDT)
本质 数据 (Data) 数据 (Data) 元数据 (Metadata)
部署方式 手动数据加载 / Apex脚本 / 数据加载工具 手动数据加载 / Apex脚本 / 数据加载工具 变更集 / Metadata API / SFDX / 包
访问方式 Apex getAll(), getInstance(name) Apex getInstance(), getOrgDefaults() SOQL (读不计入限制), Apex getAll(), getInstance()
缓存机制 应用服务器缓存 (Application Server Cache) 应用服务器缓存 (Application Server Cache) 元数据缓存 (Metadata Cache)
层级逻辑 用户 > 简档 > 组织 无内置层级 (可通过关系字段模拟)
字段类型 基本类型 (文本, 数字, 日期, 复选框等) 基本类型 (同List) 更丰富 (包括选项列表, 关系字段等)
SOQL查询限制 不适用 (非SOQL访问) 不适用 (非SOQL访问) 读取操作不计入SOQL查询限制
DML限制 受DML行数和语句限制 受DML行数和语句限制 创建/更新/删除受元数据部署限制 (非DML)
记录访问控制 公开读写 (通过“管理自定义设置”权限控制) 公开读写 (通过“管理自定义设置”权限控制) 通过简档/权限集控制元数据API访问
测试类支持 需要在测试类中创建数据 (@isTest(SeeAllData=true) 或手动插入) 需要在测试类中创建数据 (同List) 记录在测试类中默认可见 (因为是元数据)
关系能力 可创建元数据关系字段
打包能力 仅设置定义可打包,数据需手动处理 仅设置定义可打包,数据需手动处理 定义和记录均可打包

深入解读几个关键点:

  1. 数据 vs. 元数据: 这是最根本的区别。元数据意味着配置是应用定义的一部分,随代码一起版本控制、部署和管理。数据则需要独立于代码进行管理,增加了环境同步的复杂性。
  2. 部署: CMDT的元数据特性使其在DevOps流程中具有巨大优势。想象一下,你更新了一个API端点,使用CMDT,这个变更可以无缝地通过CI/CD管道推送到各个环境。而使用Custom Settings,你可能需要在每个环境手动更新,或者编写复杂的数据迁移脚本,容易出错且效率低下。
  3. 访问与Governor Limits: 虽然Custom Settings访问不计入SOQL查询,但CMDT通过SOQL访问同样不计入查询限制(仅限读取),这使得CMDT在需要复杂查询或筛选配置数据时更加灵活,同时保持了高性能。例如,你可以用WHERE子句轻松过滤CMDT记录。Custom Settings的getAll()会加载所有记录到内存,对于非常大的数据集可能存在内存隐患,而SOQL查询CMDT则更可控。
  4. 层级逻辑: Hierarchy Custom Setting的内置层级是其独特优势,对于需要基于用户/简档进行精细化控制的场景非常方便。CMDT虽然没有内置层级,但可以通过在CMDT上添加用户/简档查找字段,然后在Apex或Flow中实现类似的逻辑,虽然需要额外编码,但提供了更大的灵活性。
  5. 测试: CMDT记录在测试类中默认可见,极大地简化了单元测试的编写。测试Custom Settings则通常需要创建测试数据,或者(不推荐地)使用@isTest(SeeAllData=true)

决策框架:何时选择哪一个?

好了,理论和对比都清楚了,现在是最实际的问题:面对具体需求,到底该选谁?

选择 List Custom Settings 当:

  • 你需要存储组织级别的、相对静态的键值对或列表数据。
  • 数据不需要作为应用程序元数据的一部分进行部署(例如,可以通过管理员界面轻松维护)。
  • 配置逻辑简单,不需要基于用户或简档的层级覆盖。
  • 更新频率不高,或者可以接受手动更新或简单脚本更新。
  • 实例: 邮政编码与地区的映射、国家代码列表、固定的转换率(如果不需要部署)。
  • 思考: “这更像是一份全局参考数据清单吗?” 如果是,List Custom Setting可能是个简单直接的选择。

选择 Hierarchy Custom Settings 当:

  • 你需要根据用户或简档提供不同的配置值。
  • 层级覆盖逻辑(用户 > 简档 > 组织)完全符合你的需求。
  • 数据不需要作为应用程序元数据的一部分进行部署。
  • 允许管理员或特定用户能够方便地为自己或他人调整设置。
  • 实例: 为特定支持团队开启调试日志记录、控制不同用户组看到的功能模块、设置用户个性化的默认记录类型。
  • 思考: “这个设置需要因人而异,并且Salesforce的默认层级查找能满足我吗?” 如果是,Hierarchy Custom Setting是首选。

选择 Custom Metadata Types (CMDT) 当:

  • 配置信息是应用程序核心逻辑的一部分,需要与代码一起打包和部署
  • 你需要利用变更集、Metadata API 或 SFDX 在不同环境间迁移配置。
  • 你需要更丰富的字段类型,特别是关系字段来构建复杂的配置结构。
  • 你需要通过SOQL 查询配置数据(例如,在Apex或Flow中根据条件动态获取配置),并且希望避免SOQL查询限制
  • 你需要对配置记录进行更严格的治理和版本控制
  • 配置数据需要在单元测试中轻松访问而无需创建测试数据。
  • 你需要构建可分发的应用程序包(Managed/Unmanaged Package)
  • 实例: 存储集成服务的端点、密钥和超时设置;定义复杂的折扣规则引擎参数;管理动态流程或UI元素的配置;存储国家/地区特定的验证规则。
  • 思考: “这个配置是应用代码运行的基础吗?我需要像部署代码一样部署它吗?我需要更复杂的结构或查询能力吗?” 如果答案是肯定的,那么CMDT几乎总是更好的选择。

高级考量与实践建议

  • 性能: 三者都利用了缓存机制,访问速度通常很快。CMDT的元数据缓存通常被认为更健壮。对于大量记录(成千上万条),CMDT的SOQL查询可能比getAll()加载整个List Custom Setting更高效。
  • 安全性: Custom Settings的记录级访问通常是公开的,其安全性主要通过“管理自定义设置”权限来控制谁可以修改定义和数据。CMDT的记录访问可以通过元数据API的权限控制,并且可以在Apex中实现更细粒度的逻辑控制。
  • 迁移路径: 如果你现有应用大量使用了Custom Settings,并且遇到了部署或管理的痛点,可以考虑逐步迁移到CMDT。这可能需要编写一次性的迁移脚本,并重构访问这些配置的代码(从Apex方法调用改为SOQL查询或CMDT的Apex方法)。
  • Flow 和 Process Builder: 这三种机制都可以在Flow和Process Builder中访问,但方式略有不同。CMDT可以通过Get Records元素使用SOQL查询,非常灵活。Custom Settings通常通过公式或Apex Action访问。
  • 未来趋势: Salesforce 明显在持续投入和推荐使用CMDT作为配置管理的首选方案。新功能和优化更可能出现在CMDT上。

总结

选择正确的配置存储机制是Salesforce应用架构设计中的一个重要环节。简单回顾一下:

  • List Custom Settings: 适用于简单的、组织级别的、非层级的、不需要元数据部署的“数据”列表。
  • Hierarchy Custom Settings: 适用于需要基于用户/简档进行层级覆盖的、不需要元数据部署的“数据”设置。
  • Custom Metadata Types (CMDT): 适用于需要作为元数据进行部署、版本控制和管理的应用程序配置,提供更强的灵活性、治理能力和查询能力,是现代Salesforce开发中管理配置的首选和推荐方式。

下次当你需要存储配置信息时,问自己:它是应用定义的一部分吗?需要和代码一起部署吗?需要层级逻辑吗?需要复杂的查询或关系吗?通过回答这些问题,结合本文的分析,相信你能自信地做出最佳选择,构建出更健壮、更易于维护的Salesforce应用。

配置选择困难症终结者 SalesforceCustom SettingsCustom Metadata TypesSalesforce开发Salesforce架构

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8972