data-systems-coding-lens

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Data Systems Coding Lens

数据系统编码视角

Catch data failure modes before they reach production. Apply it when a change touches persistent data, background work, or production operational risk; UI copy, styling, and throwaway scripts do not need it.
Two leitwörter anchor every pass. Say them by name as you work:
  • Source of truth: the one place that durably owns each fact. Caches, indexes, and read models are derived and must be rebuildable from it.
  • Idempotent: a retried or replayed write produces the same result the second time: no duplicate money, emails, jobs, or records.
在 data failure modes 波及生产环境之前将其发现。当变更涉及 persistent data、background work 或生产运营风险时,应用此视角;UI 文案、样式和一次性脚本无需使用。
每次审查都围绕两个关键词展开。工作中要明确说出它们:
  • Source of truth:持久保存并唯一拥有每项事实的地方。Cache、index 和 read model 都是派生数据,必须能够从 Source of truth 重建。
  • Idempotent:被 retry 或 replay 的 write 第二次执行时产生相同结果:不会造成重复付款、重复邮件、重复 job 或重复记录。

First pass: the state boundary

第一遍审查:状态边界

  1. What data is created, updated, deleted, cached, derived, or emitted, and what is its source of truth?
  2. Which paths are asynchronous, retried, replayed, or user-visible?
  3. Which invariant makes the feature wrong if it breaks, and where does the code enforce it?
  4. Which failure would be silent, expensive, or hard to repair?
On a small change, fold this into the work. When shared data contracts or production records are involved, write the answers down before editing.
  1. 哪些数据会被创建、更新、删除、缓存、派生或发出?它们的 Source of truth 是什么?
  2. 哪些路径是异步的,会在重试或重放后执行,或会直接影响用户?
  3. 哪项 invariant 失效会使功能出错?代码在哪里 enforce 它?
  4. 哪种 failure 会悄无声息地发生、代价高昂或难以修复?
对于小型变更,可将这些问题融入实际工作。当涉及共享数据契约或生产数据记录时,应在编辑代码前写下答案。

Checks

检查项

Work through the areas the change touches.
Contracts and evolution. Old writers with new readers, and new writers with old readers, must both work. Look at nullability, enum growth, identifier stability, time zones, and migration defaults on existing rows. State the deploy order. Prefer a change that ships across several deploys, a migration that can pause and resume, and a rollback path. Name the flag, column, or job that needs cleanup afterward.
Query and storage. Find what grows with users, tenants, rows, events, or time. Look for N+1 round trips, missing index coverage, unstable pagination sorts, and transaction or lock scope. For a cache, name the key shape and its cardinality, the invalidation trigger, and how much staleness the flow tolerates.
Reliability. Trace a crash between two writes, an external call that succeeds while the local write fails, and a local write that succeeds while the external call times out. Every retry path is idempotent: an idempotency key, a unique constraint, or a version check. Poison messages have a dead-letter destination. Every file, lock, transaction, subscription, timer, and socket has one owner and is released on success, failure, and cancellation. When correctness depends on hidden timing, make the sequencing explicit with state, a queue, a lock, a transaction, or a version check.
Concurrency and distribution. When more than one process, worker, region, store, or external system is involved, state which operations need strong consistency and which can reconcile later. Check two actors updating one entity, read-after-write needs, clock dependence, leases, and any assumption of a global order. Derived state must be rebuildable from the source of truth. Process topology itself belongs to
distributed-systems-patterns
.
Operability. An operator can detect and repair the failure from the logs, metrics, and traces of the real production path.
逐一检查变更涉及的领域。
契约与演进。 旧 writer 配合新 reader,以及新 writer 配合旧 reader,都必须正常工作。检查 nullability、enum growth、identifier stability、time zones,以及现有数据行上的 migration defaults。明确 deploy 顺序。优先采用可跨多次 deploy 发布的变更、可暂停并恢复的 migration,以及明确的 rollback path。指出之后需要清理的 flag、column 或 job。
查询与存储。 找出会随用户、租户、行、事件或时间增长的数据。检查 N+1 round trips、缺失的 index coverage、不稳定的 pagination sort,以及 transaction 或 lock scope。对于 cache,应明确 key 结构及其 cardinality、invalidation trigger,以及该流程能够容忍多少 staleness。
可靠性。 追踪以下场景:两次 write 之间发生 crash;external call 成功但 local write 失败;local write 成功但 external call timeout。每条 retry 路径都必须具备 idempotent 能力,例如 idempotency key、unique constraint 或 version check。Poison message 必须有 dead-letter destination。每个 file、lock、transaction、subscription、timer 和 socket 都必须只有一个 owner,并在成功、失败和取消时都被释放。当正确性依赖隐蔽的 timing 时,应使用 state、queue、lock、transaction 或 version check 显式定义执行顺序。
并发与分布式。 当涉及多个 process、worker、region、store 或 external system 时,应明确哪些操作需要 strong consistency,哪些操作可以稍后 reconcile。检查两个 actor 更新同一 entity、read-after-write 需求、对 clock 的依赖、leases,以及任何关于 global order 的假设。派生状态必须能够从 Source of truth 重建。Process topology 本身属于
distributed-systems-patterns
的范畴。
可运维性。 运维人员能够通过真实生产路径的 logs、metrics 和 traces 发现并修复故障。

Verification

验证

Test at the real boundary the risk lives on: invariant and idempotency unit tests, integration tests against the database, queue, cache, or external API, migrations run against existing data shapes, concurrency tests for races and duplicate work, and query-plan or load checks when cardinality is the risk.
Report each finding as the failure case, why it matters, the fix, and how to verify it. When the lens changes the work, name the state or invariant, the mitigation, and its verification in one line of the final response.
在风险实际存在的边界进行测试:针对 invariant 和 idempotency 编写单元测试;针对 database、queue、cache 或 external API 编写 integration tests;针对现有数据结构运行 migration;编写 concurrency tests 以检测 race 和重复工作;当 cardinality 构成风险时,执行 query-plan 或 load checks。
报告每个发现时,应包含 failure case、其重要性、修复方式以及验证方法。当此视角改变了实施方式时,应在最终回复中用一行说明所涉及的状态或 invariant、缓解措施及其验证方式。