DynamoDB中的可选二级索引

14

我正在将持久层从Riak迁移到DynamoDB。我的数据模型包含一个可选的业务标识字段,希望能够作为替代键进行查询。

看起来DynamoDB辅助索引不能为null并需要一个范围键,因此尽管与Riak的辅助索引名称相似,但这使其看起来完全不同。

除了将数据放入外部搜索索引之外,是否有一种优雅的方法可以高效地查询我的可选字段?


1
根据我的过去经验,查询需要同时查询主索引和次要索引。关键是你不能仅通过次要索引进行查询。这可能已经在此期间发生了变化,但我怀疑。您可以轻松运行查询以检查此内容。 - andreimarinescu
1
谢谢Andrei;那就是我得出的结论。最终,我查询了我的Elasticsearch索引以通过业务标识符检索数据。这有点滥用搜索索引,但必须这样做。 - nullPainter
2个回答

27
当你提出这个问题时,DynamoDB还没有全局二级索引: http://aws.amazon.com/about-aws/whats-new/2013/12/12/announcing-amazon-dynamodb-global-secondary-indexes/ 现在,它有了。
最好将本地二级索引视为第二个范围键,并且作为其功能。@andreimarinescu是正确的: 您仍然必须通过项目的哈希键查询,只是使用辅助索引,您可以在范围键上使用DynamoDB查询的有限子集比较运算符(例如大于、等于、小于等)。因此,您仍然需要知道正在进行比较的“哈希桶”。
全局二级索引有点不同。它们更像是您表格的第二个版本(Amazon以类似的方式按预配吞吐量向您收费)。您可以将表的非主键属性用作全局二级索引中的主键属性,并相应地查询它们。
例如,如果您的表如下:
|**Hash key**: Item ID | **Range Key**: Serial No | **Attribute**: Business ID |
--------------------------------------------------------------------------------
|           1          |        12345             |             1A             |
--------------------------------------------------------------------------------    
|           2          |        45678             |             2B             |
-------------------------------------------------------------------------------- 
|           3          |        34567             |            (empty)         |
--------------------------------------------------------------------------------
|           3          |        12345             |             2B             |
--------------------------------------------------------------------------------

然后,使用本地二级索引的Business ID,您可以执行类似于“查找所有哈希键为3且业务ID等于2B的项目”的查询,但您无法执行“查找所有业务ID等于2B的项目”的查询,因为辅助索引需要一个哈希键。
如果您添加了一个全局二级索引,使用业务ID,则可以执行此类查询。实质上,您为表提供了一个替代主键。您可以执行像“查找所有业务ID等于2B的项目,并获取项目2-456783-12345作为响应”这样的查询。
稀疏索引在DynamoDB中可以很好地工作;并不是所有项目都具有业务ID,这可以使您保持索引的预配吞吐量低于表的预配吞吐量,这取决于您预计有多少项目具有业务ID。

全局二级索引就像是复制了一份带有不同哈希键的表。这意味着您的存储使用量将增加。例如,如果我的表占用100MB的空间,使用二级索引将使其使用200MB的空间。这是真的吗? - Emil
@batmaci 有一定程度的正确性。我的意思是,您将不得不为全局二级索引的表支付额外的预配吞吐量。请注意,您不必为表格加倍预配吞吐量-您可以独立设置主要吞吐容量和索引吞吐容量。我认为它实际上并不需要将数据的实际存储大小加倍,但这是亚马逊处理的实现细节,您不必担心。 - rpmartz

0

使用LSI也可以实现相同的功能。 只需确保不向该属性写入任何数据。

在我的场景中,对于一个LSI,我写了一个空字符串(""),这是不允许的。我跳过了排序键的初始化,它运行得很好。

基本上,DynamoDB甚至不会为该行创建该属性。

下面解释了行为的详细信息

如果始终需要密钥,如何创建稀疏索引?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接