如何在dynamodb中使用主键id的自动增量

pra*_*nay 51 amazon-dynamodb

我是dynamodb的新手.我想在使用putitemdynamodb 时自动增加id值.

有可能吗?

tie*_*er1 45

DynamoDB不提供开箱即用的功能.您可以在应用程序中生成一些内容,例如对于大多数系统而言"应该"足够独特的UUID.

我注意到你使用的是Node.js(我删除了你的标签).这是一个提供UUID功能的库:node-uuid

自述文件的示例

var uuid = require('node-uuid');
var uuid1 = uuid.v1();
var uuid2 = uuid.v1({node:[0x01,0x23,0x45,0x67,0x89,0xab]});
var uuid3 = uuid.v1({node:[0, 0, 0, 0, 0, 0]})
var uuid4 = uuid.v4();
var uuid5 = uuid.v4();
Run Code Online (Sandbox Code Playgroud)

  • 这个答案应该标记为正确的答案.还值得注意的原因是:您希望统一分配键,而自动递增会导致分布不均匀.有关更多信息,请参阅此文章:https://forums.aws.amazon.com/thread.jspa?messageID = 312527以及AWS文档:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ BestPractices.html (6认同)
  • FWIW 我将这种方法(UUID 作为哈希键)与 Dynamo 一起使用,并且效果很好。 (2认同)
  • 使用 uuid,因为现在已弃用 node-uuid。 (2认同)

vla*_*man 37

这是DynamoDB中的反模式,可以跨多个分区/分片/服务器进行扩展.由于扩展限制,DynamoDB不支持自动增量主键,并且无法保证跨多个服务器.

更好的选择是从多个索引组装主键.主键最多可以为2048个字节.选项很少:

  1. 使用UUID作为您的密钥 - 可能是基于时间的UUID,使其独特,均匀分布并带有时间价值
  2. 使用随机生成的数字或时间戳+随机(可能是位移),如:ts << 12 + random_number
  3. 使用其他服务或DynamoDB本身生成增量唯一ID(需要额外调用)

以下代码将在DynamoDB中自动递增计数器,然后您可以将其用作主键.

var documentClient = new AWS.DynamoDB.DocumentClient();
var params = {
  TableName: 'sampletable',
  Key: { HashKey : 'counters' },
  UpdateExpression: 'ADD #a :x',
  ExpressionAttributeNames: {'#a' : "counter_field"},
  ExpressionAttributeValues: {':x' : 1},
  ReturnValues: "UPDATED_NEW" // ensures you get value back
};
documentClient.update(params, function(err, data) {});
// once you get new value, use it as your primary key
Run Code Online (Sandbox Code Playgroud)

我个人最喜欢的是在http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram上使用时间戳+随机灵感来自Instagram的Sharding ID代.

以下函数将为特定分片生成id(作为参数提供).这样你就可以得到唯一的密钥,它是从时间戳,分片编号组装而成的.和一些随机性(0-512).

var CUSTOMEPOCH = 1300000000000; // artificial epoch
function generateRowId(shardId /* range 0-64 for shard/slot */) {
  var ts = new Date().getTime() - CUSTOMEPOCH; // limit to recent
  var randid = Math.floor(Math.random() * 512);
  ts = (ts * 64);   // bit-shift << 6
  ts = ts + shardId;
  return (ts * 512) + (randid % 512);
}
var newPrimaryHashKey = "obj_name:" + generateRowId(4);
// output is: "obj_name:8055517407349240"
Run Code Online (Sandbox Code Playgroud)

  • @vladaman 使用 `var randid = Math.floor(Math.random() * 512); 的意义是什么?... randid % 512` 它应该在第一行提供 0 到 511 之间的数字。对这样的数字使用模 512 不会改变该数字。 (2认同)
  • @TheAnimatrix 分区键应该用于将通常一起访问的数据逻辑分组在一起。具有相同分区键的数据通常会在物理上靠近其他数据存储,以优化数据检索。这就是 dynamo 支持分区键和排序键的原因。分区键相同,排序键递增,它们在一起是唯一的。我认为这个答案具有误导性,因为在链接的文章中,IG 正在做自己的分片而不是使用发电机。我认为您不想使用发电机创建这样的密钥。 (2认同)