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

时间:2016-05-06 12:22:48

标签: amazon-dynamodb

我是dynamodb的新手。我想在putitem与dynamodb一起使用时自动增加id值。

有可能吗?

5 个答案:

答案 0 :(得分:40)

DynamoDB并不提供开箱即用的功能。您可以在应用程序中生成一些内容,例如UUIDs" should"对大多数系统来说都是独一无二的。

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

来自README的示例

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();

答案 1 :(得分:28)

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

更好的选择是从多个索引组装主键。主键最多可以为2048个字节。几乎没有选择:

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

    我个人最喜欢的是使用时间戳+随机灵感来自Instagram的http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-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"
    

答案 2 :(得分:0)

您可能可以使用AtomicCounters

  

借助AtomicCounters,您可以使用UpdateItem操作来实现   原子计数器-递增的数字属性,   无条件地,而不会干扰其他写入请求。 (所有   写入请求将按照接收到的顺序进行应用。)   使用原子计数器,更新不是幂等的。其他   字,每次调用UpdateItem时数值都会递增。

     

您可以使用原子计数器来追踪访问者的数量   网站。在这种情况下,您的应用程序将增加一个数字   值,而不考虑其当前值。如果是UpdateItem操作   失败,应用程序可以简单地重试该操作。这个会   会有两次更新计数器的风险,但您可能可以忍受   网站访问者的数量被高估或低估了。

答案 3 :(得分:0)

如果您使用的是NoSQL Dynamo DB,然后使用Dynamoose,则可以轻松设置默认唯一ID,这是简单的用户创建示例

// User.modal.js

withSources()

// User.controller.js

const dynamoose = require("dynamoose");
const { v4: uuidv4 } = require("uuid");

const userSchema = new dynamoose.Schema(
  {
    id: {
      type: String,
      hashKey: true,
    },
    displayName: String,
    firstName: String,
    lastName: String,
  },
  { timestamps: true },
);

const User = dynamoose.model("User", userSchema);

module.exports = User;

答案 4 :(得分:0)

遇到一个类似的问题,我需要在表中自动增加主键。我们可以使用一些随机化技术来生成随机密钥并使用它进行存储。但这不是增量方式。

如果您需要一些增量方式,则可以使用Unix Time作为主键。不能保证可以得到准确的增量值(一对一),但是是的,每条记录的插入都会相对于插入每条记录的时间差异采用增量方式。

如果您不想读取整个表并获取最后一个let arrayBase64 = btoa([34,34....]) ... ,然后对其进行递增,则不是一个完整的解决方案。

以下是使用NodeJS在DynamoDB中插入记录的代码:

id