数据库与 .NET 基础

面向 .NET 开发者的 Salesforce 数据库基础:把 SQL 技能映射到 SOQL 查询、SOSL 文本搜索、查询优化与 DML 数据操作。...

📅 2026/10/4 ✍️ ponybai 🏷️ salesforce, developer, headless

从 SQL 迁移到 SOQL

slide_2

本单元面向熟悉 SQL 的 .NET 开发者,通过对比 SQL 与 SOQL,理解 Salesforce 对象、编写查询、过滤与关系查询。

理解对象并构建查询

slide_3

Salesforce 平台提供强大的数据库。你熟悉 SQL Server 里数据存储在表和行中,而 Salesforce 用对象(object)存储数据。对象包含表的所有功能,还有更多增强:对象由若干字段(field)组成(对应数据库的列),数据存储在对象的记录(record)中(对应行)。

对象有两种类型:

  • 标准对象(Standard Objects):Salesforce 自带,如 Account、Contact、Opportunity、Lead。
  • 自定义对象(Custom Objects):为存储应用特有信息而创建,如 Merchandise、Orders、Invoices。

对象还有关系字段,定义不同对象记录之间的关联——本质上是主键和外键,但更灵活。对象不仅存储数据,还提供 UI(选项卡、页面布局、相关列表),以及访问管理、验证、公式、历史跟踪等内置功能,无需自己实现 ORM 或 CRUD UI。

对 SQL 开发者来说,SOQL 很熟悉——SELECT、FROM、WHERE、ORDER BY、LIMIT 都一样。关键区别:

  • 没有 SELECT *——必须显式指定字段(多租户环境,用 FIELDS(ALL) 返回你有权限访问的字段)。
  • 没有 JOIN 关键字——用点表示法(dot notation)访问关系。
  • 自定义字段以 __c 结尾。

用 Developer Console 的 Query Editor 构建查询(相当于你的 SQL Server Management Studio):

SELECT Name, Industry, AnnualRevenue
FROM Account
WHERE Industry = 'Technology'
ORDER BY Name ASC
LIMIT 10

过滤与关系查询

slide_4

过滤(Filtering)的运算符和 SQL 一样:=、!=、<、>、<=、>=、IN、NOT IN、LIKE,并用 AND、OR、NOT 组合条件。

关系查询(Relationship Queries)取代了 SQL 的 JOIN,有两种基本类型:

  • 子到父(Child-to-Parent):用点表示法访问父对象字段。SELECT FirstName, LastName, Account.Name FROM Contact(相当于 SQL 的右外连接)。点表示法最多可向上遍历五级。
  • 父到子(Parent-to-Children):在 SELECT 里用嵌套子查询。SELECT Name, (SELECT FirstName, LastName FROM Contacts) FROM Account(相当于左外连接)。注意嵌套查询里的关系名要用复数(Contacts),自定义对象还要加 __r 后缀。

聚合(Aggregates)和 SQL 很像:AVG()、COUNT()、COUNT_DISTINCT()、MIN()、MAX()、SUM(),配合 GROUP BY 和 HAVING。例如 SELECT Industry, COUNT(Id) FROM Account GROUP BY Industry。注意 SOQL 没有 AS 关键字,字段别名只在聚合查询中可用。

编写 SOSL 查询

slide_5

本单元学习 SOSL(Salesforce 对象搜索语言)——跨多个对象进行全文文本搜索。

SOSL 语法与子句

slide_6

要跨多个 sObject 执行基于文本的查询,用 SOSL(Salesforce Object Search Language)。作为 .NET 开发者,你可能熟悉 Microsoft SQL Server 全文搜索(MS FTS)或 Lucene.Net。SOSL 底层就是 Lucene,但 Salesforce 已帮你配置好,无需安装或维护索引——写 SOSL 查询很容易。

FIND {searchTerm} IN SearchGroup RETURNING ObjectType(fields)

SOSL 语法三部分:

  • FIND 子句:必需,后面跟搜索词(单词或短语),支持通配符 *(匹配零个或多个字符)和 ?(匹配单个字符)。
  • IN 子句:指定搜索的字段范围——ALL FIELDS、NAME FIELDS、EMAIL FIELDS、PHONE FIELDS。注意「ALL FIELDS」并非字面意义上所有字段,对大多数标准/自定义对象默认只搜 name、email、phone、sidebar 字段。
  • RETURNING 子句:指定返回哪些对象和字段。RETURNING Account(Name), Contact(LastName, FirstName)。搜索结果以 List<List<SObject>> 返回,results[0] 是 Account 匹配项、results[1] 是 Contact 匹配项。

在 Query Editor 中搜索词用花括号 {joey}(Apex 代码里用单引号)。SOSL 还支持昵称搜索(仅限 Account、Contact、Lead、User 的英文搜索)。

SOQL 还是 SOSL?查询单个对象、知道明确条件用 SOQL;不知道数据在哪个对象、需要跨多个对象搜索用 SOSL(尤其是对象之间不相关时)。

编写高效查询

slide_7

本单元学习查询优化——Salesforce 查询优化器、构建选择性查询、理解索引,以及用查询计划工具评估性能。

最佳实践与选择性查询

slide_8

高效的查询不仅性能更好,还能避免触及 governor limits(多租户平台每个同步事务最多 100 条 SOQL 查询、最多检索 50,000 条记录)。查询优化器(Query Optimizer)像交通警察一样把查询路由到合适的索引,为每条查询的每个潜在执行路径分配成本,选择最优执行计划。

构建选择性查询(Selective Query)的关键是在 WHERE 里过滤索引字段,让返回记录数少于总数的 10%。自动索引的字段包括:

  • Id(主键)、Name、OwnerId、CreatedDate、SystemModStamp(注意它被索引而 LastModifiedDate 没有)。
  • RecordType、主从关系字段、查找关系字段。
  • 唯一字段(Unique)、外部 ID 字段(External ID)。

要避免的非选择性模式:

  • 查询空值:WHERE Custom_Field__c = null。
  • 否定运算符:!=、NOT LIKE、EXCLUDES。
  • 前导通配符:LIKE '%smi%'(无法用索引)。
  • 对文本字段用比较运算符:>、< 等。

选择性 = 快查询 + 低 governor limit 消耗:查询你需要的 100 条记录,而不是 100,000 条不需要的。

查询计划工具

slide_9

查询计划工具(Query Plan Tool)让你看到查询优化器的幕后工作——相当于 SQL 的 EXPLAIN PLAN。它默认未启用,先在 Developer Console 里通过 Help > Preferences 勾选 Enable Query Plan,Query Editor 里就会出现 Query Plan 按钮。

在 Query Editor 输入查询,点击 Query Plan,可以看到:

  • 使用了哪个索引(或显示 TableScan 表示未命中索引)。
  • 估算成本(cost)。
  • 基数(cardinality,返回多少条记录)。
  • 查询是否具有选择性。

对比两条结果相同但性能不同的查询:SELECT Id, CaseNumber FROM Case WHERE Status != 'New' 会触发 TableScan(不好);而 SELECT Id, CaseNumber FROM Case WHERE IsClosed = true 能命中索引(好)。在开发 org 里数据少时差异不明显,但在有数百万记录的 org 里,这个差异是决定性的。

不要靠猜——用 Query Plan 工具测量查询的真实性能。注意它无法评估 SOSL 查询,但 SOSL 也要关注性能。

用 DML 修改记录

slide_10

最后一个单元学习 DML(数据操作语言)——相当于 SQL 的 INSERT/UPDATE/DELETE,用于管理 Salesforce 记录。

DML 语句与两种执行方式

slide_11

Salesforce 用 SOQL 查询数据,而管理数据用 DML(Data Manipulation Language)。可用的 DML 语句:

  • insert — 插入新记录。
  • update — 更新现有记录。
  • upsert — 单条语句内创建新记录或更新现有记录(用指定字段或 ID 判断是否存在)。
  • delete — 删除记录。
  • undelete — 从回收站恢复记录。
  • merge — 合并最多三条同类型记录,删除其余并重新挂接相关记录。

在 Apex 里执行 DML 有两种方式:

  • DML 语句(更简单):insert acct; 全有或全无——一条失败则全部回滚。
  • Database 类方法(更多控制):Database.SaveResult[] results = Database.insert(acct, false); 可选的 allOrNone 参数设为 false 时允许部分成功,每条结果都有 isSuccess() 和 getErrors()。

对 SQL 开发者来说,最关键的区别是批量设计:始终对 List 集合操作,绝不要循环处理单条记录——一次处理 200 条记录的 DML 语句只算作 150 条 DML 限额里的 1 条。


文章来源:Trailhead - Database & .NET Basics