mcpField
V
vtex-io-data-access-patterns

vtex-io-data-access-patterns

github.com/vtex数据与数据库471.1k 次安装2 周前更新
代码仓库

关于 vtex-io-data-access-patterns

面向 VTEX IO 应用开发者的数据访问技能,帮助为数据选择存储位置、明确权威数据源并规划读取方式。重点约束配置存储用途,并避免全量扫描和不必要的数据副本。

主要功能

  1. 01按数据类型选择存储
  2. 02明确权威数据源
  3. 03采用有界查询与分页
  4. 04制定缓存新鲜度规则
  5. 05审查数据访问设计

适用场景

  1. 01设计新应用的数据流
  2. 02评估 Master Data 或 VBase
  3. 03审查大数据集读取代码

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/vtex/skills --skill vtex-io-data-access-patterns

安装后在 Claude Code 中输入/vtex-io-data-access-patterns确认已加载。

详细介绍

数据访问与存储模式

适用场景

当主要问题是数据应存放在哪里,以及 VTEX IO 应用应如何读取或写入数据时,使用此技能。

  • 为 IO 应用设计新的数据流
  • 决定使用应用设置、配置应用、Master Data、VBase 还是 VTEX 核心 API
  • 审查读取或写入大型、重复或关键数据集的代码
  • 在现有 API 周围引入缓存层或派生的本地视图

以下情况不使用此技能:

  • 详细的 Master Data 架构或实体建模
  • 应用设置或配置应用的架构设计
  • 身份验证令牌或策略,例如 AUTH_TOKEN、STORE_TOKEN 或清单权限
  • 服务运行时规格或并发调优

决策规则

为每类数据选择合适的存放位置
  • 对于由商家或运营人员管理的稳定配置,例如功能开关、凭据、外部基础 URL 和行为开关,使用应用设置或配置应用。
  • 对于属于该账户、需要验证、筛选、搜索、分页或生命周期管理的结构化自定义业务记录,使用 Master Data。
  • 对于简单的键值文档、辅助快照或类似缓存的 JSON 载荷,通常按键读取而非广泛搜索时,使用 VBase。
  • 对于已属于 VTEX 核心领域(如订单、目录、定价或物流)的数据,使用 VTEX 核心 API。
  • 对于属于其他系统且 VTEX IO 仅与之集成的数据,使用外部存储或外部 API。
明确数据的唯一真实来源
  • 对于订单、产品、价格、库存等核心商务领域,将 VTEX 核心 API 视为唯一真实来源。
  • 除非有明确所有权的狭义派生用途,否则不要将完整订单、目录记录、价格或库存镜像到 Master Data 或 VBase。
  • 如果 IO 应用需要本地副本,只存储该应用所需的最少字段或派生视图,并在需要时从权威数据源重新获取完整详情。
  • 不要将应用设置或配置应用用作通用运营数据存储。
有意设计读取和缓存
  • 优先使用 API 级别的筛选、分页、字段选择和有界读取,而不是将完整数据集加载到 Node 中并在内存里筛选。
  • 只有在重复读取确有必要,且缓存视图具有明确的失效或新鲜度规则时,才使用缓存。
  • 当后台任务或事件流水线需要持久化处理状态时,只存储重试和幂等所需的状态及关联数据。
  • 除非用例明确要求持久化且由应用拥有的审计记录,否则不要在 Master Data 和 VBase 中存放长期日志、跟踪记录或无界历史数据。

硬性约束

约束:不得将配置存储用于运营数据存储

应用设置和配置应用必须用于表示配置,不得用于存储事务记录、无界列表或频繁变化的运营状态。

原因

将配置存储用作数据存储会模糊系统边界,使工作区行为更难理解,并破坏依赖设置保持精简且稳定的工具和流程的预期。

检测

如果在 settingsSchema、配置应用载荷或与设置相关的 API 中看到记录数组、日志、历史记录、订单或其他不断增长的运营载荷,请立即停止,并将这些数据迁移到 Master Data、VBase、核心 API 或外部存储中。

正确

{
  "settingsSchema": {
    "type": "object",
    "properties": {
      "enableModeration": {
        "type": "boolean"
      }
    }
  }
}

错误

{
  "settingsSchema": {
    "type": "object",
    "properties": {
      "orders": {
        "type": "array"
      }
    }
  }
}
约束:核心系统必须继续作为各自业务领域的事实来源

VTEX 核心系统,例如 Orders、Catalog、Pricing 和 Logistics,必须继续作为各自业务领域的主要事实来源。

重要原因

将本地 IO 副本视为核心业务领域的主要存储,会造成数据对账偏差、读取过时,以及基于过时数据做出业务决策。

检测方法

如果应用将完整的订单载荷、商品文档、库存快照或价格表存储在 Master Data 或 VBase 中,然后将这些副本用作业务决策的主要依据,请立即停止,并围绕权威上游数据源重新设计流程。

正确做法

const order = await ctx.clients.oms.getOrder(orderId)

ctx.body = {
  orderId: order.orderId,
  status: order.status,
}

错误做法

const cachedOrder = await ctx.clients.masterdata.getDocument({
  dataEntity: 'ORD',
  id: orderId,
})

ctx.body = cachedOrder
约束:读取大量数据时,必须避免全表扫描和内存过滤

访问大型或不断增长的数据集时,必须使用有界查询、筛选、分页或预先计算的派生视图,而不是全表扫描和大范围内存过滤。

重要原因

无界读取效率低下、难以扩展,并且随着数据集增长,很容易导致服务行为变得脆弱。

检测方法

如果你发现代码会从 Master Data、VTEX API 或外部存储中获取整个集合,然后在 Node 中为常规请求流程筛选或汇总结果,请立即停止,并重新设计访问路径。

正确做法

const documents = await ctx.clients.masterdata.searchDocuments({
  dataEntity: 'RV',
  fields: ['id', 'status'],
  where: 'status=approved',
  pagination: {
    page: 1,
    pageSize: 20,
  },
})

错误做法

const allDocuments = await ctx.clients.masterdata.scrollDocuments({
  dataEntity: 'RV',
  fields: ['id', 'status'],
})

const approved = allDocuments.filter((doc) => doc.status === 'approved')

首选模式

每次设计数据方案时,都先回答以下四个问题:

  1. 这些数据属于谁?
  2. 谁是事实来源?
  3. 应用将如何查询这些数据?
  4. 应用是否真的需要存储本地副本?

然后有意识地选择:

  • 稳定配置信息使用应用设置或配置应用
  • 应用领域拥有的结构化自定义记录使用 Master Data
  • 简单的键值文档或类似缓存的载荷使用 VBase
  • 权威商务数据使用 VTEX 核心 API
  • VTEX 之外拥有的数据使用外部存储或 API

如果应用存储本地副本,请确保副本体量小、属于派生数据,并且明确次于权威数据源。

常见失败模式

  • 将应用设置用作记录、历史数据或大型列表的通用存储。
  • 将完整订单、商品或价格从 VTEX 核心系统镜像到 Master Data 或 VBase,作为并行的事实来源。
  • 获取完整数据集后,仅为常规请求流程在内存中筛选、排序或汇总。
  • 使用 Master Data 或 VBase 存储无界的调试日志或事件转储。
  • 添加缓存,却没有明确的新鲜度、失效或所有权规则。
  • 在处理程序中分散临时的数据访问决策,而没有明确事实来源和存储决策。

审查清单

  • 这些数据确实属于配置信息吗?还是应该存储在 Master Data、VBase、核心 API 或外部系统中?
  • 是否明确了权威事实来源?
  • 是否将 VTEX 核心系统视为订单、目录、价格、库存及类似业务领域的权威数据源?
  • 本地存储是否仅限于应用真正拥有的数据或范围有限的派生视图?
  • 是否在适当情况下通过筛选、字段选择和分页来限制读取范围?
  • 缓存或本地副本是否有明确的新鲜度和失效规则?

相关技能

参考资料

评论

支持 Markdown