2014-01-27 123 views

回答

61

本地二级索引仍然依赖于原始的哈希键。 当您提供带有散列+范围的表时,请将LSI视为散列+范围1,散列+范围2 ..散列+范围6。 您可以获得5个更多的范围属性来查询。 另外,只有一个预配置吞吐量。

全局二级索引定义了一个新的范例 - 每个索引不同的哈希/范围键。
这打破了每个表的一个散列键的原始用法。 这也是为什么在定义GSI时,您需要为每个索引添加预配置吞吐量并为其付费。

有关差异的更多详细信息可在GSI announcement

+1

可能会添加1)二级索引,无论是LSI还是GSI,与唯一性无关 – user1322092

+0

您最多可以拥有5个本地二级索引,这就是为什么Chen Harel说:“您还可以获得5个范围属性查询“_”。 –

9

找到另一种方式来解释:LSI可帮助您与相同散列键的项目做额外的查询。 GSI可以帮助您对“整个桌子”上的项目进行类似的查询。非常有用。

如果您有用户个人资料表: unique-id,name,email。在这里,如果您需要在名称表可查询,电子邮件 - 那么唯一的办法就是让他们GSI(LSI不会帮助)

22

这些是由指数的可能的搜索结果:

  • 通过哈希
  • 通过哈希+范围
  • 通过哈希+本地索引
  • 全球指数
  • 全球指数+系列指数

表中的哈希和范围索引: 这些是以前版本的Amazon AWS SDK的常用索引。

全球和本地索引: 这些都是表中创建“额外”指标,除表中的现有散列和范围索引。 全局索引与散列相似。 范围索引的行为与用于该表的散列的范围索引类似。 在你的代码的实体模型,吸气剂必须以这种方式注释:

  • 对于全局索引:

    @DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS) 
    @DynamoDBAttribute(attributeName = PROPERTY_USER) 
    public String getUser() { 
        return user; 
    } 
    
  • 关联到全球指数系列指数:

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS) 
    @DynamoDBAttribute(attributeName = PROPERTY_TIMESTAMP) 
    public String getTimestamp() { 
        return timestamp; 
    } 
    

此外,如果您通过全局索引读取表,则该表必须是最终读取(未持续读):

queryExpression.setConsistentRead(false); 
45

这里是从文档的正式定义:

全球二级索引 - 利用哈希和范围键索引可以 是从那些不同的桌子。全局二级索引 被视为“全局”,因为索引上的查询可跨越所有分区中的表中的所有 数据。

本地二级索引 - 与 表具有相同散列键但索引不同的索引。本地二级索引是“本地” ,意思是本地二级索引的每个分区的作用域为 ,其范围为具有相同散列键的表分区。

然而,差异超出了关键定义的可能性。在下表中查找将直接影响成本和精力用于维护索引的一些重要因素:

  • 吞吐量:

本地二级索引使用表中的吞吐量。当您通过本地索引查询记录时,操作会消耗表中的读取容量单位。在具有本地索引的表中执行写入操作(创建,更新,删除)时,将会有两个写入操作,一个用于索引的另一个表。两种操作都会消耗表中的写入容量单位。

当您在具有全局索引的表中执行写入操作(创建,更新,删除)时,全局二级索引具有自己的预配置吞吐量,当您查询索引时,操作将消耗索引的读取容量,会有两个写操作,一个用于索引*的另一个表。

*当定义为全球第二索引的供应量,确保您要特别注意以下要求:

为了表写成功,配置的吞吐量 设置表并且其所有的全局二级索引必须有足够的写入容量来容纳写入;否则,写入表的 将受到限制。

  • 管理:当您创建表时,才能创建

本地二级索引,也没有办法为本地二级索引添加到现有的表,也曾经在创建索引你不能删除它。

全局二级索引可以在创建表并添加到现有表时创建,删除现有全局二级索引也是允许的。

  • 读一致性:

本地二级索引支持最终还是很强的一致性,而全球第二索引仅支持最终一致性。

  • 投影:

本地二级索引允许检索未投影到索引属性(尽管具有附加成本:性能和消耗的容量单位)。使用Global Secondary Index,您只能检索投影到索引的属性。

定义到辅助索引键的唯一性的特殊考虑:

在本地二级索引,范围键值并不需要是一个给定的散列键值唯一的,同样的道理也适用于全局二级索引,关键值(散列和范围)不需要是唯一的。

来源:把它http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html

+0

感谢您的解释 –

+1

“_Global二级索引具有自己的预配置吞吐量,当您查询索引时,操作将消耗来自table_”的读取容量“ - 错误。对全局二级索引的查询或扫描会消耗索引中的容量单位,而不是基表中的容量单位。 – weakleaf

+0

固定,谢谢你的抬头。 – bsd

8

一种方法是这样的:

LSI - 可以让你同时使用多个不同的属性上的单个散列键执行查询“过滤”或限制查询。

GSI - 允许您对表中的多个哈希键执行查询,但因此会导致吞吐量增加。

更广泛的表类型的故障,以及它们如何工作的,下面:

哈希只有

正如你可能已经知道了;散列键本身必须是唯一的,因为写入已存在的散列键将覆盖现有数据。

哈希+范围

哈希键+范围-键,您可以有多个哈希键是一样的,只要他们有不同幅度的关键。在这种情况下,如果您写入已存在的哈希键,但使用尚未被该哈希键使用的范围键,它会创建一个新项目,而如果具有相同哈希+范围组合的项目它已经存在,它会覆盖匹配的项目。

想想这个的另一种方式就像是一个格式的文件。只要格式(范围)不同,您可以在同一个文件夹(表格)中使用与另一个名称(散列)相同的文件。同样,只要名称不同,就可以有多个相同格式的文件。

LSI

的LSI基本相同的散列键+范围,重点和创建项目时,除了你还必须为大规模集成电路提供值遵循相同的规则,因为它,以及;他们不能留空/空。

要说LSI是“Range-Key 2”并不完全正确,因为您不能使用(使用我之前的文件和格式类比)名为:file.format.lsifile.format.lsi2的文件。但是,您可以有file.format.lsifile.format2.lsifile.format.lsifile2.format.lsi

基本上,LSI只是一个“Filter-key”,而不是实际的Range-Key;您的基础哈希和范围值组合必须仍然是唯一的,而LSI值不必是唯一的。查看它的更简单方法可能是将LSI视为文件中的数据。您可以编写代码来查找名称为“PROJECT101”的所有文件,而不管它们的fileFormat如何,然后读取里面的数据以确定查询中应包含哪些内容以及什么被省略。这基本上是LSI的工作原理(只是没有打开文件来读取其内容的额外开销)。

GSI

对于GSI,你基本上创建另一个表中的每个GSI,但没有保持它们之间进行数据镜像多个单独的表的麻烦;这就是为什么他们花费更多的吞吐量

因此对于GSI,您可以指定fileName作为您的基础哈希密钥,并将fileFormat指定为您的基准范围密钥。然后,您可以指定一个GSI,该GSI具有fileName2的哈希键和fileFormat2的范围键。如果您愿意,您可以在fileNamefileName2上查询,不像LSI,您只能在fileName上查询。

主要优点是你只需要维护一个表而不是2个,并且每次写入主Hash/Range或GSI哈希/范围时,其他(s)会自动地也更新了,所以你不能像使用多表格设置那样“忘记”更新其他表格。另外,更新一个之前和更新另一个之前不会有丢失连接的机会,就像使用多表设置一样。

此外,GSI可以“重叠”基础哈希/范围组合。因此,如果您想以fileNamefileFormat作为您的基本散列/范围,并且将filePriorityfileName作为您的GSI,则可以。最后,GSI哈希+范围组合不必是唯一的,而基础哈希+范围组合必须是唯一的。这对于双/多表设置是不可能的,但是与GSI一样。因此,您必须在更新时为基本和GSI哈希+范围提供值;这些值都不能为空/空。

相关问题