大对象

一个大对象在 Salesforce 上存储和管理大量数据 平台。您可以存档来自其他对象的数据,也可以从外部系统引入海量数据集 到一个大对象中,以获得客户的全貌。客户端和外部系统使用 用于访问大对象数据的标准 API 集。大对象提供一致的性能, 无论您拥有 100 万条记录、1 亿条记录,还是 10 亿条记录。这个比例给出了一个大对象 它的力量并定义了它的功能。

有两种类型的大物体。

  • 标准 大 objects – 对象 由 Salesforce 定义并包含在 Salesforce 产品中。 是一个标准的大对象,它将数据存储为 Field 的一部分 审计跟踪产品。标准大对象始终可用,无法自定义。FieldHistoryArchive
  • 定制大 对象 – 新建 您创建的用于存储组织特有信息的对象。自定义大对象扩展了 Lightning Platform 提供的功能。例如,如果您正在构建一个要跟踪的应用 产品库存,创建一个自定义大对象,用于跟踪历史库存水平以进行分析和 未来的优化。本实施指南用于配置和部署自定义 big 对象。HistoricalInventoryLevels

自定义大对象用例

  • 360°全景 的 customer – 扩展 您的 Salesforce 数据模型,包括来自忠诚度计划、提要、 点击次数、结算和配置信息等。
  • 审计和 tracking – 追踪 并保持对 Salesforce 或产品使用情况的长期看法,以便进行分析或合规性 目的。
  • 历史的 存档 – 维护 访问历史数据以进行分析或合规,同时优化性能 您的核心 CRM 或 Lightning 平台应用程序。

大对象与其他对象的区别

因为一个大对象可以无限尺度地存储数据,所以它具有不同的特征 而不是其他对象,如 sObjects。大对象也存储在 闪电平台。

大物体s对象
可水平扩展的分布式数据库关系数据库
非事务性数据库事务数据库
数亿甚至数十亿条记录数以百万计的记录

这些大对象行为可确保一致且可扩展的体验。

  • 大对象仅支持对象和字段权限,不支持常规或标准共享 规则。
  • 不支持触发器、流、流程和 Salesforce 移动应用程序等功能 大物体。
  • 当您多次插入具有相同表示的相同大对象记录时, 仅创建单个记录,以便写入可以是幂等的。此行为是不同的 从 sObject,它为每个创建对象的请求创建一条记录。

对大型对象的 API 支持

您可以轻松地将自定义大对象与您的实时 Salesforce 数据集成。你可以处理大 具有 SOQL、Bulk、Chatter 和 SOAP API 的对象。

注意

这些 API 是唯一受支持的 API 适用于大物体。例如,不支持 REST API。

另见

大对象最佳实践

大型对象是独一无二的,因为它能够针对大量对象进行扩展 数据。

适用于:Salesforce Classic 和 Lightning Experience
适用于:EnterprisePerformanceUnlimited 和 Developer Edition,最多可保存 100 万条记录

使用大对象时的注意事项

  • 要定义大对象或向自定义大对象添加字段,请使用元数据 API 或 设置。
  • 大型对象支持自定义 Lightning 和 Visualforce 组件,而不是标准 UI 元素主页、详细信息页面或列表视图。
  • 每个组织最多可以创建 100 个大对象。大对象字段的限制类似 对自定义对象的限制,并取决于组织的许可证类型。
  • 您不能使用 Salesforce Connect 外部对象访问其他组织中的大对象。
  • 大型对象不支持加密。如果从标准或 自定义对象,它以明文形式存储在大对象上。如果您使用 Salesforce Shield Platform 加密、标准或自定义对象字段历史记录已加密。 对于字段历史记录,使用 Shield 字段历史记录存档对数据进行存档。大物体 尊重静态加密。Shield Platform Encryption 则不然 支持自定义大对象。

在设计时考虑弹性

大对象数据库存储数十亿条记录,是一个有利于 一致性高于可用性。该数据库旨在确保行级别的一致性。

在使用 API 或 Apex 处理大数据和写入批量记录时,您可以 在写入某些记录而未写入其他记录时遇到部分批处理失败。因为 数据库在大规模上具有高度响应性和一致性,这种类型的行为是预期的。在 在这些情况下,只需重试,直到写入所有记录。

在处理大型对象时,请牢记这些原则。

  • 写入大对象时,最佳做法是采用重试机制。重试 批处理,直到您从 API 或 Apex 方法获得成功的结果。提示要添加 记录到自定义对象并向用户显示错误,请使用该方法。请参阅异常简介 处理。addError()提示若要验证是否保存了所有记录,请检查类。请参阅 SaveResult 类 参考。Database.SaveResult
  • 不要试图弄清楚哪些记录成功,哪些记录失败。重试整个 批。
  • 大对象不支持事务。如果尝试读取或写入大对象 sObject 上的触发器、进程或流,请使用异步 Apex。异步 Apex 具有以下功能 就像隔离 DML 的接口一样 对不同的 sObject 类型进行操作,以防止混合 DML 错误。Queueable
  • 由于客户端代码必须重试,因此请使用异步 Apex 写入大对象。由 异步写入,可以更好地处理数据库生命周期事件。

另见

定义和部署自定义大对象

您可以使用元数据 API 或在设置中定义自定义大对象。在定义和 部署一个大对象,您可以查看它或在设置中添加字段。在部署了大型 对象,则无法编辑或删除索引。要更改索引,请从新的大 对象。要在设置中定义大对象,请参阅 Salesforce 帮助。

定义自定义大对象

通过元数据 API 定义自定义大对象,方法是创建包含以下内容的 XML 文件 其定义、字段和索引。

  • 对象文件 – 为每个对象创建一个文件 定义自定义大对象、其字段及其索引。
  • 权限集/配置文件 – 创建权限集或配置文件以指定权限 对于每个字段。这些文件不是必需的,但需要授予 访问用户。默认情况下,对自定义大对象的访问是 限制。
  • package file – 为元数据 API 创建一个文件 指定要迁移的元数据的内容。注意包装 文件与 Salesforce 的打包功能无关。此文件 不是已解锁、非托管或托管的包。它只是一个文件 由元数据 API 使用。

注意

虽然自定义大对象使用 CustomObject 元数据类型,但某些 参数对于大型对象是唯一的,其他参数则不适用。具体的 适用于大型对象的元数据参数在此中概述 公文。

自定义大对象的命名约定

对象名称在所有标准对象、自定义对象、外部对象中必须是唯一的 对象,以及组织中的大对象。在 API 中,自定义大对象的名称 后缀为两个下划线,后跟小写字母“b”(__b)。为 例如,一个名为“HistoricalInventoryLevels”的大对象被视为 HistoricalInventoryLevels__b该组织的 WSDL 中。我们建议您制作 对象标签在组织中的所有对象中是唯一的 – 标准、自定义、外部和 大物体。

CustomObject 元数据

字段名称字段类型描述
deploymentStatusDeploymentStatus (枚举类型 字符串)自定义大对象的部署状态(适用于所有大对象 对象)Deployed
fields自定义字段[]大对象中字段的定义
fullName字符串大对象的唯一 API 名称
indexes索引[]指数的定义
label字符串UI 中显示的大对象名称
pluralLabel字符串UI 中显示的字段复数名称

CustomField 元数据

字段名称字段类型描述
fullName字符串字段的唯一 API 名称。
label字符串UI 中显示的字段名称。
lengthint字段的长度(以字符为单位)(Text 和 LongTextArea 字段 仅)。中所有文本字段中的字符总数 索引不能超过 100。要增加此值,请联系 Salesforce 客户支持。注意电子邮件字段为 80 个字符。电话字段 是 40 个字符。设计时请牢记这些长度 您的索引,因为它们计入 100 个字符 限制。
pluralLabel字符串UI 中显示的字段复数名称。
precisionint数字值的位数。例如,数字 256.99 的精度为 5(仅限数字字段)。
referenceTo字符串查阅字段的相关对象类型 (查阅字段 仅)。
relationshipName字符串UI 中显示的关系的名称(查找字段 仅)。
required布尔指定该字段是否为必填字段。属于 的索引必须标记为必需。
scaleint数字小数点右边的位数 价值。例如,数字 256.99 的小数位数为 2(数字 仅限字段)。
type字段类型字段类型。支持日期时间、电子邮件、查找、号码、电话、 Text、LongTextArea 和 URL。注意不能包含 LongTextArea 和 索引中的 URL 字段。

注意

自定义字段不支持唯一性。

索引元数据

表示在自定义 big 中定义的索引 对象。使用此元数据类型定义 自定义大对象。

字段名称字段类型描述
领域索引字段[]索引中字段的定义。
标签字符串必填。此名称用于指代用户界面中的大对象。 在 API 版本 41.0 及更高版本中可用。

IndexField 元数据

定义构成索引的字段、它们的顺序和排序 方向。定义字段的顺序决定了字段的列出顺序 在索引中。

注意

索引中所有文本字段的总字符数不能超过 100. 要增加此值,请联系 Salesforce 客户支持。

字段名称字段类型描述
名字字符串必填。属于索引的字段的 API 名称。此值必须 匹配相应值 字段,并标记为必填。fullName警告什么时候 通过 SOQL 查询一个大对象记录,并将结果作为参数传递给 删除 API,如果任何索引字段名称具有前导或尾随空格,则 无法删除大对象记录。
排序方向字符串必填。索引中字段的排序方向。有效值为升序和降序。ASCDESC

创建用于部署的元数据文件

以下 XML 摘录创建可部署的元数据文件。每个客户 交互对象表示在线视频中单个会话中的客户数据 游戏。、 和 字段定义索引,查找字段将 客户与 Account 对象的交互。Account__cGame_Platform__cPlay_Date__cCustomer_Interaction__b.object

<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <deploymentStatus>Deployed</deploymentStatus>

    <fields>
        <fullName>In_Game_Purchase__c</fullName>
        <label>In-Game Purchase</label>
        <length>16</length>
        <required>false</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>
    
    <fields>
        <fullName>Level_Achieved__c</fullName>
        <label>Level Achieved</label>
        <length>16</length>
        <required>false</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>
    
    <fields>
        <fullName>Lives_This_Game__c</fullName>
        <label>Lives Used This Game</label>
        <length>16</length>
        <required>false</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>
    
    <fields>
        <fullName>Game_Platform__c</fullName>
        <label>Platform</label>
        <length>16</length>
        <required>true</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>
    
     <fields>
        <fullName>Score_This_Game__c</fullName>
        <label>Score This Game</label>
        <length>16</length>
        <required>false</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>

    <fields>
        <fullName>Account__c</fullName>
        <label>User Account</label>
        <referenceTo>Account</referenceTo>
        <relationshipName>Game_User_Account</relationshipName>
        <required>true</required>
        <type>Lookup</type>
    </fields>

    <fields>
        <fullName>Play_Date__c</fullName>
        <label>Date of Play</label>
        <required>true</required>
        <type>DateTime</type>
    </fields>

    <fields>
        <fullName>Play_Duration__c</fullName>
        <label>Play Duration</label>
        <required>false</required>
        <type>Number</type>
        <scale>2</scale>
        <precision>18</precision>
    </fields>

    <indexes>
        <fullName>CustomerInteractionsIndex</fullName>
        <label>Customer Interactions Index</label>
        <fields>
            <name>Account__c</name>
            <sortDirection>DESC</sortDirection>
        </fields>
        <fields>
            <name>Game_Platform__c</name>
            <sortDirection>ASC</sortDirection>
        </fields>
        <fields>
        <name>Play_Date__c</name>
        <sortDirection>DESC</sortDirection>
        </fields>        
    </indexes>
    
    <label>Customer Interaction</label>
    <pluralLabel>Customer Interactions</pluralLabel>
</CustomObject>

包.xml

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>*</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>PermissionSet</name>
    </types>
    <version>41.0</version>
</Package>

Customer_Interaction_BigObject.权限集

<?xml version="1.0" encoding="UTF-8"?>
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
     
    <label>Customer Interaction Permission Set</label>
     
    <fieldPermissions>
        <editable>true</editable>
        <field>Customer_Interaction__b.In_Game_Purchase__c</field>
        <readable>true</readable>
    </fieldPermissions>
     
    <fieldPermissions>
        <editable>true</editable>
        <field>Customer_Interaction__b.Level_Achieved__c</field>
        <readable>true</readable>
    </fieldPermissions>
     
    <fieldPermissions>
        <editable>true</editable>
        <field>Customer_Interaction__b.Lives_This_Game__c</field>
        <readable>true</readable>
    </fieldPermissions>
     
     
    <fieldPermissions>
        <editable>true</editable>
        <field>Customer_Interaction__b.Play_Duration__c</field>
        <readable>true</readable>
    </fieldPermissions>
     
    <fieldPermissions>
        <editable>true</editable>
        <field>Customer_Interaction__b.Score_This_Game__c</field>
        <readable>true</readable>
    </fieldPermissions>
     

</PermissionSet>

使用元数据 API 部署自定义大对象

使用 Metadata API 和 Ant Migration Tool 进行部署。在构建文件以部署自定义大对象时,请确保对象文件位于名为 objects 的文件夹中,并且权限集文件位于 在名为 permissionsets 的文件夹中。将 package.xml 文件放在根目录中,而不是放在 子文件夹。

在设置中查看自定义大对象

部署自定义大对象后,您可以通过登录到 组织,然后从“设置”中输入“快速查找”框,然后选择“大” 对象Big Objects

若要查看其字段和关系,请单击大对象的名称。

另见

使用 Zip 文件部署和检索元数据

和调用用于部署和检索 .zip 文件。在 .zip 文件是一个项目清单 (package.xml),其中列出了要执行的操作 检索或部署,以及组织到文件夹中的一个或多个 XML 组件。

deploy()retrieve()

注意

组件是元数据类型的实例。例如,是自定义对象的元数据类型,并且 该组件是 自定义对象。CustomObjectMyCustomObject__c

在 .zip 文件中检索或部署的文件可能是未打包的组件 驻留在组织中(例如标准对象)或打包组件 驻留在命名包中。

注意

您可以部署或 一次最多可检索 10,000 个文件。AppExchange 软件包使用不同的限制: 最多可包含 35,000 个文件。已部署或检索的 .zip 的最大大小 文件大小为 39 MB。如果文件在解压缩的文件夹中解压缩,则大小限制 是 400 MB。

  • 如果使用 Ant 迁移工具执行 部署解压后的文件夹,首先压缩文件夹中的所有文件。这 解压缩文件夹中未压缩组件的最大大小为 400 MB 或更少 取决于压缩比。如果文件具有高压缩比, 您总共可以迁移大约 400 MB,因为压缩的大小 将小于 39 MB。但是,如果组件不能被压缩太多,比如 二进制静态资源,可以迁移小于 400 MB。
  • 元数据 API base-64 对组件进行编码 它们被压缩了。生成的 .zip 文件不能超过 50 MB,即 SOAP 消息的限制。Base-64 编码会增加有效负载的大小,因此 在编码之前,压缩的有效负载不能超过大约 39 MB。
  • 您可以执行大 对象仅在定义其索引时才被定义。如果在安装程序中创建了一个大对象,并且 尚未定义索引,则无法检索它。retrieve()

每个 .zip 文件都包含一个项目清单、一个名为 package.xml 的文件以及一组包含 组件。清单文件定义您尝试执行的组件 在 .zip 文件中检索或部署。清单还定义了 API 版本 用于部署或检索。

注意

您可以编辑项目 清单,但如果您修改它所包含的组件列表,请小心。当你 部署或检索组件时,元数据 API 会引用 清单,而不是 .zip 文件中的目录。

下面是一个示例包 .xml 文件。您可以检索 通过在元素中指定元数据类型的 fullName 字段值来获取元数据类型的单个组件。您还可以 使用 检索元数据类型的所有组件。members<members>*</members>

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>MyCustomObject__c</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>CustomTab</name>
    </types>
    <types>
        <members>Standard</members>
        <name>Profile</name>
    </types>
    <version>59.0</version>
</Package>

可以在 package.xml 中定义以下元素。

  • <fullName>包含服务器端的名称 包。如果不存在,则 package.xml 定义客户端包。<fullName>unpackaged
  • <types>包含元数据类型的名称 (例如,) 和 成员(例如,) 为 检索或部署。您可以在清单文件中添加多个元素。CustomObjectmyCustomObject__c<types>
  • <members>包含组件的 fullName,例如 。该调用对 确定特定组件的 fullName 元数据类型(如果要检索单个组件)。对于许多元数据 类型,您可以将 中的值替换为通配符(星号) 而不是单独列出每个成员。有关特定 type 以确定该类型是否支持通配符。 每个组件 在元数据 API 部署中必须具有唯一的名称。解析为 重复项,例如一个符号和 UTF-8 编码符号以及一对名为 xyz.typename 和 xyz.typename-meta.xml 仍然是 重复。MyCustomObject__clistMetadata()members*注意在元素中指定 Security,在名称中指定 Settings 元素。<members>
  • <name>包含元数据类型,例如 或 。在 目录。任何扩展元数据的元数据类型都是有效值。输入的名称 必须与元数据 API WSDL 中定义的元数据类型匹配。有关列表,请参阅元数据类型。CustomObjectProfile
  • <version>是使用的 API 版本号 部署或检索 .zip 文件时。当前有效值为 。59.0

有关演示如何工作的更多示例包 .xml 清单文件 使用不同的元数据子集,请参阅示例包 .xml 清单 文件。

要删除组件,请参阅从 组织。

填充自定义大对象

使用 Salesforce API 填充自定义大对象。您可以使用 CSV 文件通过 Bulk API 2.0 将数据加载到自定义大对象中。这 CSV 文件中的第一行必须包含用于将 CSV 数据映射到的字段标签 导入期间自定义大对象中的字段。

注意

批量 API 和批量 API 2.0 支持查询和插入大对象。

插入是幂等的,因此插入已存在的数据不会导致 重复。在上传数百万条记录时,重新插入非常有用。如果错误 发生时,重新插入会重新上传失败的上传,而不会出现重复数据。在 重新插入时,如果提供的索引不存在任何记录,则新记录为 插入。例如,此 CSV 文件包含要导入 Customer Interaction 的数据 对象。

Play Start,In-Game Purchase,Level Achieved,Lives Used,Platform,Play Stop,Score,Account
2015-01-01T23:01:01Z,A12569,57,7,PC,2015-01-02T02:27:01Z,55736,001R000000302D3
2015-01-03T13:22:01Z,B78945,58,7,PC,2015-01-03T15:47:01Z,61209,001R000000302D3
2015-01-04T15:16:01Z,D12156,43,5,iOS,2015-01-04T16:55:01Z,36148,001R000000302D3

使用 Apex 填充自定义大对象

使用 Apex 填充自定义大对象。

您可以使用该方法在 Apex 中创建和更新自定义大对象记录。Database.insertImmediate()

警告

不允许使用混合 DML 调用的 Apex 测试,否则会失败。如果你写 仅对大对象,测试会将错误数据插入到目标大对象中,然后 必须手动删除。若要包含对目标大对象的测试 DML 调用,请使用模拟 框架替换为存根 API。

我们建议您在插入值之前使用 Apex 方法删除前导和尾随空格,尤其是对于 主键字段中的值。此最佳实践可确保 SOQL 查询 对象稍后将按预期工作。String.trim()

在 SOQL 查询 WHERE 子句中指定索引字段时,SOQL 会删除任何前导或 在将空格与实际字段值进行比较之前,先留出空格。即使您的过滤器 字符串与插入的值匹配,不比较前导和尾随空格, 因此,筛选器不会匹配任何行。

因此,前导和尾随空格无法与已 数据处理。即使筛选器字符串与插入的值匹配,也不会匹配任何行 通过过滤器。

如果在更新插入到自定义大对象时将值设置为 NULL,则字段不会 如果它们具有现有值,则更新。若要将这些值设置为 NULL,请删除字段和 重新创建它。

重新插入索引相同但数据不同的记录会导致类似于 更新插入操作。如果存在具有索引的记录,则插入将覆盖索引 值替换为新数据。插入是幂等的,因此插入不存在的数据 导致重复。在上传数百万条记录时,重新插入非常有用。如果错误 发生时,重新插入会重新上传失败的上传,而不会出现重复数据。在 重新插入,如果提供的索引不存在记录,则插入新记录。

如果记录插入失败,该方法不会引发异常。相反,它 返回一个对象,该对象具有返回对象列表的方法。每个对象都包含有关作为 记录插入失败的结果。请参阅 Apex 开发人员指南,了解有关 错误。Database.insertImmediate()SaveResultgetErrors()Database.ErrorDatabase.ErrorSaveResult下面是 Apex 中的插入操作示例,该操作假定一个表,其中索引 由 、 和 组成。

FirstName__cLastName__cAddress__c

// Define the record.
PhoneBook__b pb = new PhoneBook__b();
pb.FirstName__c = 'John';
pb.LastName__c = 'Smith';
pb.Address__c = '1 Market St';
pb.PhoneNumber__c = '555-1212';
database.insertImmediate(pb);
// A single record will be created in the big object.
// Define the record with the same index values but different phone number.
PhoneBook__b pb = new PhoneBook__b();
pb.FirstName__c = 'John';
pb.LastName__c = 'Smith';
pb.Address__c = '1 Market St';
pb.PhoneNumber__c = '415-555-1212';
database.insertImmediate(pb);
// The existing records will be "re-inserted". Only a single record will remain in the big object.
// Define the record with the different index values and different phone number
PhoneBook__b pb = new PhoneBook__b();
pb.FirstName__c = 'John';
pb.LastName__c = 'Smith';
pb.Address__c = 'Salesforce Tower';
pb.PhoneNumber__c = '415-555-1212';
database.insertImmediate(pb);
// A new record will be created leaving two records in the big object.

另见

删除自定义大对象中的数据

使用 Apex 或 SOAP 删除自定义大对象中的数据。

Apex 方法删除数据 在自定义大对象中。声明一个 sObject,其中包含 自定义大对象的索引。sObject 的作用类似于模板。与 sObject 的字段和值将被删除。您只能指定属于部分的字段 大对象的索引。您必须指定索引中的所有字段。你不能 包含部分指定的索引或非索引字段,并且不包含通配符 支持。deleteImmediate()

如果由于容量优化而删除所有记录,请插入一两条记录 删除后空白记录,并等待 24 小时以恢复新容量 认可。

重要

使用大型对象的批处理限制为 50,000 条记录 时间。deleteImmediate()

注意

这些示例假定,当您最初插入大对象值时,您使用了 要删除的 Apex 方法 索引字段中的前导和尾随空格。请参阅使用 Apex 填充自定义大对象。String.trim()

在此示例中,、 和 是自定义大对象索引的一部分。什么时候 在子句后指定特定值,字段必须按照它们在索引中的出现顺序列出,而不显示任何值 差距。Account__cGame_Platform__cPlay_Date__cWHERE

// Declare sObject using the index of the custom big object -->
List<Customer_Interaction__b> cBO = new List<Customer_Interaction__b>();
cBO.addAll([SELECT Account__c, Game_Platform__c, Play_Date__c FROM Customer_Interaction__b WHERE Account__c = '001d000000Ky3xIAB']);

Database.deleteImmediate(cBO);

要使用 SOAP 调用,请声明 一个 sObject,其中包含要删除的字段和值。sObject 的作用类似于 模板。与 sObject 的字段和值匹配的所有行都将被删除。您可以 仅指定属于大对象索引的字段。索引中的所有字段 必须指定。不能包含部分指定的索引或未编制索引的索引 字段和通配符不受支持。此示例删除 001d000000Ky3xIAB、iOS 和 2017-11-28T19:13:36.000z 的所有行。deleteByExample()Account__cGame_Platform__cPlay_Date__c

Java 示例代码:

public static void main(String[] args) {
  try{
       Customer_Interaction__b[] sObjectsToDelete = new Customer_Interaction__b[1];
       //Declare an sObject that has the values to delete
       Customer_Interaction__b customerBO = new Customer_Interaction__b();
       customerBO.setAccount__c (“001d000000Ky3xIAB”);
       customerBO.setGame_Platform__c (“iOS”);
       Calendar dt = new GregorianCalendar(2017, 11, 28, 19, 13, 36);
       customerBO.setPlay_Date__c(dt);
       sObjectsToDelete[0] = customerBO;
       DeleteByExampleResult[] result = connection.deleteByExample(sObjectsToDelete);
  }  catch (ConnectionException ce) {
	      ce.printStackTrace();  
  }
}

注意

重复成功的操作会产生成功的结果,即使这些行已被删除也是如此。deleteByExample()

大对象可排队示例

要使用 sObject 中的触发器、进程或流读取或写入大对象, 使用异步 Apex。此示例使用异步 Apex 接口来隔离 不同的 sObject 类型,以防止混合 DML 错误。

Queueable

插入案例记录时会发生此触发器。它调用一个方法来插入 一批大对象记录并演示了部分故障情况,其中某些 记录成功,有些失败。要在此示例中为对象创建元数据文件, 使用创建用于部署的元数据文件示例中的 XML 摘录。

Customer_Interaction__b

提示

将日志记录添加到自定义对象并将错误显示到 用户,请使用该方法。请参阅简介 异常处理。addError()

// CaseTrigger.apxt

trigger CaseTrigger on Case (before insert) {
    if (Trigger.operationType == TriggerOperation.BEFORE_INSERT){
        // Customer_Interaction__b has three required fields in its row key, in this order:
        // 1) Account__c - lookup to Account
        // 2) Game_Platform__c - Text(18)
        // 3) Play_Date__c - Date/Time
        List<Customer_Interaction__b> interactions = new List<Customer_Interaction__b>();
        
        // Assemble the list of big object records to be inserted
        for (Case c : Trigger.new) {
            Customer_Interaction__b ci = new Customer_Interaction__b(
                Account__c = c.AccountId,
                // In this example, the Case object has a custom field, also named Game_Platform__c
                Game_Platform__c = c.Game_Platform__c,
                Play_Date__c = Date.today()
            );
            interactions.add(ci);
        }
        
        // CustomerInteractionHandler is an asynchronous queuable Apex class
        CustomerInteractionHandler handler = new CustomerInteractionHandler(interactions);
        System.enqueueJob(handler);
    }
}

触发器使用 Apex 接口 异步调用要插入到大对象中的方法。Queueable

// CustomerInteractionHandler.apxc

public class CustomerInteractionHandler implements Queueable {
    
    private List<Customer_Interaction__b> interactions;
    
    public CustomerInteractionHandler(List<Customer_Interaction__b> interactions) {
        this.interactions = interactions;
    }
 
    /*
     * Here we insert the Customer Interaction big object records,
     * or log an error if insertion fails.
     */
    public void execute(QueueableContext context){
        
        List<ExceptionStorage__c> errors = new List<ExceptionStorage__c>();
        
        try {
            // We have to use insertImmediate() to insert big object records.
            List<Database.SaveResult> srList = Database.insertImmediate(interactions);
            
            // Check the save results from the bulk insert
            for (Database.SaveResult sr: srList) {
                if (sr.isSuccess()) {
                       System.debug('Successfully inserted Customer Interaction.');
                } else {
                       for (Database.Error err : sr.getErrors()) {
                        // Display an error message if the insert failed
                        System.debug(err.getStatusCode() + ': ' + err.getMessage() + '; ' +
                                    'Error fields: ' + err.getFields());
                        
                        // Write to a custom object, such as ExceptionStorage__c
                        // for a more durable record of the failure
                        ExceptionStorage__c es = new ExceptionStorage__c(
                               name = 'Error',
                               ExceptionMessage__c = (err.getMessage()).abbreviate(255),
                               ExceptionType__c = String.valueOf(err.getStatusCode()),
                            ExceptionFields__c = (String.valueOf(err.getFields())).abbreviate(255)
                        );
                        errors.add(es);
                    }
                }
            }
        }
        catch (Exception e) {
            // Exception occurred, output the exception message
            System.debug('Exception: ' + e.getTypeName() + ', ' + e.getMessage());
            
            // Write any errors to a custom object as well
            ExceptionStorage__c es = new ExceptionStorage__c(
                   name = 'Exception',
                   ExceptionMessage__c = e.getMessage(),
                   ExceptionType__c = e.getTypeName()
            );
            errors.add(es);
        }
        
        // If any errors occurred, save the ExceptionStorage records
        if (errors.size() > 0) {
               insert errors;
        }
    }
}

另见

大对象查询示例

了解一些常见的大对象查询用例。

客户 360 度和过滤

在此用例中,管理员从 外部源到Salesforce大对象中,然后处理数据以丰富 Salesforce 中的客户资料。目标是存储客户交易和 大范围内的互动,例如销售点数据、订单和订单项 对象,然后处理该数据并将其与核心 CRM 数据相关联。锚固 客户交易和与核心CRM数据的交互提供了更丰富的 360 度视图,可转化为增强的客户体验。

Batch Apex 是对大型对象或 ApiEvent 进行自动处理的最佳选择, ReportEvent 或 ListViewEvent。此示例演示如何添加处理 引用相关数据。对大对象运行批处理 Apex 查询,并关联联系人信息 与那个大 对象。

public class QueryBigObjectAndContact implements Database.Batchable<sObject> {
    private String key;
	public QueryBigObjectAndContact(String keyParam) {
        key = keyParam
    }
    
    public Iterable<SObject> start(Database.BatchableContext BC) {
		return [SELECT Big_Object_Field__c, Account__c FROM Big_Object__b WHERE Big_Object_Primary_Key > key LIMIT 50000]
    }

    public void execute(Database.BatchableContext bc, List<Big_Object__b> bos){
        // process the batch of big objects and associate them to Accounts
        Map<Id, Big_Object__b> accountIdToBigObjectMap = new Map<Id, Big_Object__b>();
        for (Big_Object__b bigObject : bos) {
            accountIdToBigObjectMap.put(bigObject.Account__c, bigObject);
            key = bigObject.Big_Object_Primariy_Key__c
        }
        Map<Id, Account> accountMap = new Map<Id, Account>(
            [SELECT Id, Name, ... FROM Account WHERE Id IN :accountIdToBigObjectMap.keySet()]
        );
        for (Id accountId : accountMap.keySet()) {
            Big_Object__b bigObject = accountIdToBigObjectMap.get(accountId);
            Account account = accountMap.get(accountId);
            // perform any actions that integrate the big object and Account
        }
    }
    public void finish(Database.BatchableContext bc){
        // You can daisy chain additional calls using the primary key of the big object to get around the 50k governor limit
        QueryBigObjectAndContact nextBatch = new QueryBigObjectAndContact(key);
        Database.executeBatch(nextBatch);
    }
}

现场审计跟踪

此示例演示如何在 CSV 中查询和分析大量结果 格式。FieldHistoryArchive

例 URI

/services/data/vXX.X/jobs/query

例 发布请求

{
    "operation": "query",
    "query": "SELECT ParentId, FieldHistoryType, Field, Id, NewValue, OldValueFROM FieldHistoryArchive WHERE FieldHistoryType = ‘Account’ AND CreatedDate > LAST_MONTH"
}

使用“获取查询作业的结果”资源。

示例 CURL 请求

curl --include --request GET \
--header "Authorization: Bearer token" \
--header "Accept: text/csv" \
https://instance.salesforce.com/services/data/vXX.X/jobs/query/750R0000000zxr8IAA/results ?maxRecords=50000

这 请求结果以 CSV 文件的形式提供,可用于检查以进行审核。

实时事件监控

通过实时事件监控,您可以跟踪谁在访问机密和 Salesforce 组织中的敏感数据。您可以查看有关个人的信息 事件或跟踪事件趋势,以快速识别异常行为并采取保护措施 贵公司的数据。这些功能对于遵守法规和 审计要求。

借助实时事件,您可以监控通过 API 调用访问的数据、报告 执行和列表视图。对应的事件对象称为 ApiEvent, ReportEvent 和 ListViewEvent。查询这些事件涵盖了许多常见方案 因为超过 50% 的 SOQL 查询是使用 SOAP、REST 或批量 API 进行的。钥匙 有关每个查询的信息,例如用户名、用户 ID、处理的行、 查询的实体和源 IP 地址存储在事件对象中。你 然后,可以对事件对象运行 SOQL 查询以发现用户活动详细信息。

有关详细信息,请参阅实时事件 监控。此示例演示如何使用字段的 内容。

public class EventMatchesObject implements Database.Batchable<sObject> {
    private String lastEventDate;

    public EventMatchesObject(String lastEventDateParam) {
        lastEventDate = lastEventDateParam;
    }

    public Iterable<SObject> start(Database.BatchableContext bc) {
        return [SELECT EventDate, EventIdentifier, QueriedEntities, SourceIp, Username, UserAgent FROM ApiEvent WHERE EventDate > lastEventDate LIMIT 50000]
    }

    public void execute(Database.BatchableContext bc, List<ApiEvent> events){
        // Process this list of entities if a certain attribute matches
        for (ApiEvent event: events) {
            String objectString = 'Patent__c';
            String eventIdentifier = event.EventIdentifier;
            if (eventIdentifier.contains(objectString) {
                // Perform actions on the event that contains 'Patent__c'
            }
            lastEventDate = format(event.EventDate);
        }
    }

    public void finish(Database.BatchableContext bc){         
        // You can daisy chain additional calls using EventDate or other filter fields to get around the 50k governor limit
        EventMatchesObject nextBatch = new EventMatchesObject(lastEventDate);
        Database.executeBatch(nextBatch);
    }
}

聚合查询

此示例显示了聚合的替代方法 查询与该方法类似。

COUNT()

public class CountBigObjects implements Database.Batchable<sObject> {
    private Integer recordsCounted;
    private String key;

	public CountBigObjects(Integer recordsCountedParam, String keyParam) {
        recordsCounted = recordsCountedParam
        key = keyParam
    } 

    public Iterable<SObject> start(Database.BatchableContext bc) {
        return [SELECT Custom_Field__c FROM Big_Object__b LIMIT 25000]
    }

    public void execute(Database.BatchableContext bc, List<Big_Object__b> bos){
        // process the batch of big objects and associate them to Accounts
        Map<Id, Big_Object__b> accountIdToBigObjectMap = new Map<Id, Big_Object__b>();
        for (Big_Object__b bigObject : bos) {
            accountIdToBigObjectMap.put(bigObject.Account__c, bigObject);
        }
        Map<Id, Account> accountMap = new Map<Id, Account>(
            [SELECT Id, Name, ... FROM Account WHERE Id IN :accountIdToBigObjectMap.keySet()]
        );
        for (Id accountId : accountMap.keySet()) {
            Big_Object__b bigObject = accountIdToBigObjectMap.get(accountId);
            Account account = accountMap.get(accountId);
            // perform any actions that integrate the big object and Account
        }
    }

    public void finish(Database.BatchableContext bc) {         
        // You can daisy chain additional calls using the primary key of the big object to get around the 50k governor limit
        CountBigObjects nextBatch = new CountBigObjects(recordsCounted, key);
        Database.executeBatch(nextBatch);
    }
}

在报告和仪表板中查看大对象数据

在处理大数据和数十亿条记录时,构建报告是不切实际的 或直接从该数据创建仪表板。请改用批量 API 编写一个查询,该查询提取 您感兴趣的较小、具有代表性的数据子集。您可以将其存储为 数据集,并在报告、仪表板或任何其他 Lightning Platform 中使用它 特征。

  1. 确定包含需要报告的数据的大对象。在这个 例如,Ride__b Big 对象包含完整的数据集。
  2. 创建自定义对象。此对象包含大对象数据的工作数据集,该数据集 你想报告。在此示例中,我们使用 Bike_Rental__c 自定义 对象。
    1. 在自定义对象的“可选功能”下,单击“允许” 报告
    2. 将自定义字段添加到对象中,使其与要从 大对象。
  3. 创建一个 SOQL 查询,该查询通过从大 对象添加到自定义对象中。提示确保您的工作数据集始终是最新的,以确保准确 报告时,将此作业设置为每晚运行。
  4. 使用您创建的工作数据集生成报表。
    1. 在“设置”中,在“快速查找”框中输入报告类型”,然后选择“报告类型”。
    2. 创建自定义报告类型。
    3. 对于主对象,从步骤 2 Bike_Rental__c中选择自定义对象。
    4. 将报表设置为“已部署”。
    5. 运行报表。

现在,您不仅可以在报表中使用工作数据集中的信息,还可以在报表中使用工作数据集中的信息。 也存在于仪表板或任何其他 Lightning Platform 功能中。

具有大对象的 SOQL

您可以通过以下方式查询大对象索引中的字段 使用标准 SOQL 命令的子集。

构建索引查询,从索引中定义的第一个字段开始,而不 查询中第一个字段和最后一个字段之间的间隙。您可以使用或在任何 字段,但只能使用一次。可以使用范围运算 、 、 或仅对查询的最后一个字段使用。=ININ<><=>=

提示

当您将子句与 只有一个参数,例如 ,它等价于 使用 ,例如 。 为清楚起见,我们建议您使用 这种情况。INFirstName IN(‘Charlie’)=FirstName=’Charlie’=不支持子查询。不要在你的 查询。例如,不支持此查询

Select CreatedById, CreatedDate, Created_Date__c, Id, Legacy_Record_ID__c, Parent_Case__c, SystemModstamp, Text_Body__c FROM Archived_Email_Message__b WHERE Parent_Case__c IN(select id from case where owner.id in ('00580000008BBVUAA4'))

您可以在查询中包含系统字段 、 和 。CreatedByIdCreatedDateSystemModstamp

若要保证查询结果的顺序,请使用子句。ORDER BY

这些查询假定您有一个表,其中的索引由 、 和 定义。LastName__cFirstName__cPhoneNumber__c

此查询指定索引中的所有三个字段。在这种情况下,筛选器可以使用范围 算子。PhoneNumber__c

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c='Kelly' AND FirstName__c='Charlie' AND PhoneNumber__c='2155555555'

此查询仅指定索引中的前两个字段。在本例中, 筛选器可以使用范围 算子。FirstName__c

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c='Kelly' AND FirstName__c='Charlie'

此查询仅指定索引中的第一个字段。筛选器可以使用范围运算符。LastName__c

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c='Kelly'

此查询使用第一个上的运算符 字段。IN

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c IN ('Kelly','Jones','Capulet','Montague') AND FirstName__c='Charlie'

此查询不起作用,因为查询中存在缺口。FirstName__c

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c='Kelly' AND PhoneNumber__c='2155555555'

此查询也不起作用,因为它使用运算符 两次。

IN

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c IN ('Kelly','Jones') AND FirstName__c IN ('Charlie','Lisa')

此查询有效,即使它在子句中似乎有两个运算符。 但因为第二个只有一个 参数,它等效于等于运算符,所以它是允许的。INWHEREIN

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c IN ('Kelly','Jones') AND FirstName__c IN ('Charlie')

为清楚起见,我们建议您重写前面的 SOQL 语句,如下所示。

SELECT LastName__c, FirstName__c, PhoneNumber__c
FROM Phone_Book__b
WHERE LastName__c IN ('Kelly','Jones') AND FirstName__c='Charlie'

不允许对大型对象执行 SOQL 操作

  • 生成索引查询时,不要在第一个和最后一个之间留出间隙 字段。
  • 运算符 、 、 和 在任何查询中都无效。!=LIKENOT INEXCLUDESINCLUDES
  • 聚合函数在任何查询中都无效。
  • 若要检索结果列表,请不要在查询中使用该字段。包含在查询中仅返回具有空 ID 的结果 (00000000000000000 或 00000000000000AAA)。IdId注意当您使用开发人员控制台执行以下操作时 从资源生成查询,该字段将自动包含在内。查询大对象 Developer Console,从 生成的查询。IdId

另见

API 生命周期终止政策

查看哪些 REST API 版本受支持、不受支持或不可用。

Salesforce 承诺支持每个 API 版本至少 3 个 自首次发布之日起的年。为了提高质量和性能 API,有时不再支持超过 3 年的版本。

Salesforce 通知使用计划的 API 版本的客户 为 折旧 至少 1 年后,对版本的支持将结束。

Salesforce API 版本版本支持状态版本停用信息
版本 31.0 至 59.0支持。
版本 21.0 至 30.0截至 22 年夏季,这些版本已被弃用,并且没有 Salesforce 支持的时间更长。从 25 年夏季开始,这些 版本将停用且不可用。Salesforce Platform API 版本 21.0 到 30.0 停用
版本 7.0 至 20.0自 22 年夏季起,这些版本已停用,并且 不能利用的。Salesforce Platform API 版本 7.0 到 20.0 停用

如果你 请求任何资源或使用已停用的 API 版本 REST API 中的操作 返回错误代码。410:GONE

识别 从旧的或不受支持的 API 版本发出的请求,请使用 API 总使用量事件类型。