入门阅读约 2 分钟

DynamoDB 中的 GSI vs LSI

全局二级索引(GSI)和本地二级索引(LSI)都能让你用一个不是表键的属性来 Query。但它们不可互换——正是这些差异决定了某个模式该用哪一个。

DynamoDB 中 GSI 和 LSI 的区别是什么?

全局二级索引可以用任意顶层标量属性(字符串、数字或二进制)作为它的分区键,拥有自己独立的容量,可以随时添加——但只服务最终一致读取。本地二级索引沿用表相同的分区键、搭配一个不同的排序键,支持强一致读取并共享表的容量,但必须随表一起创建。

那些要紧的差异

GSILSI
分区键任意标量(S/N/B)与表相同
排序键任意标量(S/N/B)任意标量(S/N/B)
何时创建随时仅在建表时
一致性仅最终一致可用强一致
容量独立拥有共享表的
写入传播异步(最终一致)同步(原子)
每表上限20(默认,可上调)5(硬性)
10 GB 分区上限有(每个 PK)

一条经验法则

  • 需要一个不同的(例如按 status 而不是 customer 查订单)?你需要一个 GSI——LSI 无法重新分区。
  • 需要在同一分区内换一种排序方式——LSI 沿用表精确的分区键、只换入一个不同的排序键——在建表时就已定下,并要求读取?那 LSI 合适。

这个选择归结为一个问题——你在改哪个键:

YesNo, same PKnew sort keyNeed to queryanother way?Differentpartition key?GSILSIOwn partitionsEventual readsOwn capacityAdd anytimeShared partitionStrong reads OKShared capacityTable-creation only

不同的分区键就逼着你用 GSI;在同一分区上换一个不同的排序键,是唯一适合 LSI 的情形。

实践中大多数团队几乎清一色地用 GSI:它们可以后加、独立伸缩,也不受 10 GB 每分区上限的约束。把单个 GSI 的键重载以服务多种模式——见单表设计

如果你为了消灭一次 Scan 而添加一个 GSI,记住它有自己独立的读/写容量。用定价计算器来估算这份额外成本,并试用 DynoTable 在你锁定一个索引之前检视它的投影属性。

更新于