3

我们正在考虑将 DynamoDB 用于预期的大型数据集。我来自强大的 SQL 背景,所以 No-SQL 的思维方式对我来说是新的。

我有一个问题和设计,但遇到了似乎是死胡同。
文档说要确保您的哈希键被广泛分布以帮助提高性能,这是有道理的。

我将为用户记录各种数据点/操作。对我来说,哈希键应该是用户 ID,而我的范围键可以是执行的操作。

现在,如果我想要用户 #1 执行的所有操作,我可以轻松查询。
但是,如果我想要所有执行操作 X 的用户,那么如果没有表扫描,我就无法做到这一点。从查询文档

Query 操作使用表主键直接访问表中的项目,或使用索引键从索引中访问项目。您必须提供特定的哈希键值

因此,我似乎仅限于从特定用户获取数据,除非我愿意进行表扫描,这会更慢并且消耗许多容量单位。

我认为,我的问题最终是一个设计问题。也许我在 No-SQL 方面遗漏了一些东西?我的哈希键应该是别的吗?或者仅仅是我的要求不适合 No-SQL(更具体地说,DynamoDB)?

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

4

3 回答 3

2

满足您允许两种类型查询要求的 DynamoDb 方法是将数据存储在两张表中,一张带有哈希键 user-id 和范围键 action-id,一张带有哈希键 action-id 和范围键 user-id .

您应该考虑是否需要两个表中的所有数据,或者一个可以是汇总表。例如,假设您的可能操作数量有限。与其将每个操作的完整记录放在用户键控表中,您可能需要一个表,每个用户只有一行:用户 ID 的哈希键,以及第二列,它是多值的并且是一个列表用户至少执行一次的任何操作 ID。

于 2013-04-24T22:38:00.453 回答
1

我猜全局二级索引选项更好,因为你得到一个表。

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

于 2013-05-28T01:00:24.100 回答
1

您必须创建一个全局二级索引(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-username-gsi索引并查找具有提供值的任何 actionId 哈希。使用ProjectionExpression将仅返回每个项目的指定属性值,如果这成为问题,则会降低吞吐量。我希望这有助于回答你的问题。

于 2016-01-13T17:49:52.617 回答