2013-04-24 87 views
3

我们正在考虑为DynamoDB提供一个大型数据集。我来自强大的SQL背景,所以No-SQL思维方式对我来说是新的。Amazon DynamoDB表格设计和查询

我有一个问题和设计,但跑到似乎是死胡同。
该文件说,以确保您的哈希密钥广泛分布,以帮助性能,好吧,这是有道理的。

我将为用户记录各种数据点/动作。我认为散列键应该是用户标识,而我的范围键可以是执行的操作。

现在,如果我想要用户#1执行的所有操作,我可以轻松地查询它。
但是,如果我想要所有执行操作X的用户,我不能在没有表扫描的情况下执行此操作。从Query documentation

查询操作直接使用表主键或从使用索引键的索引访问表中的项目。 您必须提供特定的散列键值

所以它似乎我仅限于从特定用户获取数据,除非我愿意做一个table scan,这是慢,消耗了许多能力的单位。

我的问题是,我认为,最终是一个设计问题。说到No-SQL,可能我错过了一些东西?我的散列键应该是别的吗?或者仅仅是我的需求不适合No-SQL(更具体地说,DynamoDB)?

它几乎就好像散列键是DynamoDB的一种分组。我考虑将哈希键更改为我们打算实施的操作,但后来我没有广泛分发我的密钥...

+1

你是幸运的,只有6天前二级指标(指数?)支持公布。参见[这里](http://aws.amazon.com/about-aws/whats-new/2013/04/18/amazon-dynamodb-announces-local-secondary-indexes/)。 – 2013-04-24 22:42:49

回答

2

DynamoDb满足您的要求以允许这两种查询类型的方法是存储两个表中的数据,一个使用散列键user-id和range key action-id,另一个使用散列键action-id和范围键user-id。

而且您应该考虑是否需要两个表中的所有数据,或者是否需要汇总表。例如,假设您的可能操作数量有限。您可能需要一个只有一行的表,而不是每个用户的完整记录:一个用户id的散列键,第二列是多值的,并且是一个列表用户至少执行过一次的任何操作ID。

1

我想global secondary indexes选项更好,因为你得到一个表。

创建两个表将创建冗余和额外的工作,以在任何一个表上执行任何CUD(创建,更新,删除)操作时保持一致性。

1

您必须创建一个Global Secondary Index(GSI)。它所做的是创建与原始键不同的第二对散列键和范围键。然后,您可以通过在参数中包含索引名称来查询同一个表。

实施例JS:

var table = tablename; 
var index = actionId-username-gsi; 
var action = actionId; 
var params = { 
    TableName : table, 
    IndexName : index, 
    KeyConditionExpression : 'actionId = :v_actionId', 
    ExpressionAttributeValues : { 
     ':v_actionId': { N : action } 
    }, 
    ProjectionExpression : 'actionId, username' 
}; 
ddb.query(params, err) { 
    if(err) { 
     // Oh well 
    } else { 
     // Do something 
    } 
}; 

这将查询actionId-用户名-GSI索引并查找任何actionId与提供的值散列。使用ProjectionExpression将只返回每个项目的指定属性的值,如果这种情况成为问题,则会降低吞吐量。我希望这有助于回答你的问题。