SuperAPI AI 工具集

nosql-expert

数据与分析

查看项目

更新于 10-15 09:05

技能介绍

用途

本技能面向分布式宽列存储与键值存储(具体为 Apache Cassandra 和 Amazon DynamoDB),提供专业的心智模型与设计模式。与 SQL(建模数据实体)或文档存储(如 MongoDB)不同,这类分布式系统要求先建模查询。

何时使用

  • 面向规模设计:从单节点数据库迁移到分布式集群。
  • 技术选型:评估或使用 Cassandra、ScyllaDB 或 DynamoDB。
  • 性能调优:排查现有 NoSQL 系统中的“热分区”或高延迟。
  • 微服务:实现“每服务一库”模式,且需要高度优化的读取。

心智转变:SQL 与分布式 NoSQL 对比

特性 SQL(关系型) 分布式 NoSQL(Cassandra/DynamoDB)
数据建模 建模实体 + 关系 建模查询(访问模式)
连接 CPU 密集,读取时进行 写入时预计算(反规范化)
存储成本 昂贵(尽量减少重复) 便宜(为读取速度复制数据)
一致性 ACID(强一致) BASE(最终一致)/ 可调
扩展性 垂直(更大机器) 水平(更多节点/分片)

黄金法则:在 SQL 中,你设计数据模型以回答任意查询;在 NoSQL 中,你设计数据模型以高效回答特定查询。

核心设计模式

1. 查询优先建模(访问模式)

通常无法在不迁移或新建表/索引的情况下“稍后再加一个查询”。

流程:

  1. 列出所有实体(User、Order、Product)。
  2. 列出所有访问模式(“按 Email 获取 User”“按用户获取订单并按日期排序”)。
  3. 专门设计表以单次查找服务这些模式。

2. 分区键为王

数据根据分区键(PK)分布到物理节点。

  • 目标:数据与流量的均匀分布。
  • 反模式:使用低基数 PK(如 status="active" 或 gender="m")会产生热分区,吞吐量受限于单个节点容量。
  • 最佳实践:使用高基数键(用户 ID、设备 ID、复合键)。

3. 聚类键 / 排序键

在分区内,数据按聚类键(Cassandra)或排序键(DynamoDB)在磁盘上排序。

这支持高效的范围查询(如 WHERE user_id=X AND date > Y),实际上为特定检索需求预排序了数据。

4. 单表设计(邻接表)

主要用途:DynamoDB(概念也适用于其他场景)。将多种实体类型存入一张表,以实现预连接读取。

PK(分区) SK(排序) 数据字段...
USER#123 PROFILE { name: "Ian", email: "..." }
USER#123 ORDER#998 { total: 50.00, status: "shipped" }
USER#123 ORDER#999 { total: 12.00, status: "pending" }

查询:PK="USER#123"。结果:一次网络请求获取用户资料及所有订单。

5. 反规范化与冗余

不要害怕将相同数据存入多张表以服务不同查询模式。

  • 表 A:users_by_id(PK: uuid)
  • 表 B:users_by_email(PK: email)

权衡:必须管理跨表数据一致性(通常使用最终一致性或批量写入)。

具体指导

Apache Cassandra / ScyllaDB

  • 主键结构:((Partition Key), Clustering Columns)
  • 无连接、无聚合:不要尝试 JOIN 或 GROUP BY。在单独的计数表中预计算聚合。
  • 避免 ALLOW FILTERING:若生产环境出现此语句,说明数据模型有误,意味着全集群扫描。
  • 写入廉价:插入和更新只是追加到 LSM 树。相比读取效率,不必过于担心写入量。
  • 墓碑:删除是昂贵的标记。避免在标准表中使用高频删除模式(如队列)。

AWS DynamoDB

  • GSI(全局二级索引):用 GSI 创建数据的替代视图(如“按日期搜索订单”而非按用户)。注意:GSI 是最终一致的。
  • LSI(本地二级索引):在同一分区内以不同方式排序数据。必须在建表时创建。
  • WCU / RCU:理解容量模式。单表设计有助于优化消耗的容量单位。
  • TTL:使用 Time-To-Live 属性自动过期旧数据(免费删除),而不产生墓碑。

专家检查清单

在最终确定 NoSQL 模式之前:

  • 访问模式覆盖:每个查询模式是否都映射到特定表或索引?
  • 基数检查:分区键是否有足够唯一值以均匀分散流量?
  • 分区拆分风险:任何单个分区(如单个用户的订单)是否会无限增长?(若超过 10GB,需要“分片”分区,如 USER#123#2024-01)。
  • 一致性要求:应用能否容忍此读取模式的最终一致性?

常见反模式

  • ❌ 分散-聚集:查询所有分区以查找一项(Scan)。
  • ❌ 热键:将所有“周一”数据放入一个分区。
  • ❌ 关系建模:创建 Author 和 Book 表并试图在代码中连接。(应改为在 Author 中嵌入 Book 摘要,或在 Book 中复制 Author 信息)。