如何在DynamoDB中创buildUUID?

在我的数据库scheme中,我需要一个自动增量主键。 我怎样才能实现这个function?

PS要访问DynamoDB,我使用dynode,Node.js.模块。

免责声明:我是Dynamodb-mapper项目的维护者

直观的自动增量键的工作stream程:

  1. 得到最后的柜台位置
  2. 加1
  3. 使用新的数字作为对象的索引
  4. 保存新的计数器值
  5. 保存对象

这只是为了解释底层的想法。 千万不要这样做,因为它不是primefaces的。 在一定的工作量下,您可以将相同的ID分配给两个不同的对象,因为它不是primefaces的。 这会导致数据丢失。

解决scheme是使用primefacesADD操作以及UpdateItem的ALL_NEW :

  1. 自动生成一个ID
  2. 使用新的数字作为对象的索引
  3. 保存对象

在最坏的情况下,应用程序在保存对象之前崩溃,但不会冒两次分配相同的ID的风险。

还有一个问题:在哪里存储最后的ID值? 我们select了:

{ "hash_key"=-1, #0 was judged too risky as it is the default value for integers. "__max_hash_key__y"=N } 

当然,要可靠地工作,所有插入数据的应用程序都必须知道这个系统,否则你可能会(再次)覆盖数据。

最后一步是自动化过程。 例如:

 When hash_key is 0: atomically_allocate_ID() actual_save() 

有关实现细节(Python,对不起),请参阅https://bitbucket.org/Ludia/dynamodb-mapper/src/8173d0e8b55d/dynamodb_mapper/model.py#cl-67

说实话,我的公司并没有在生产中使用它,因为在大多数情况下,最好是find另一个关键字,比如用户,一个ID,一个交易logging,一个date时间…

我在dynamodb-mapper的文档中写了一些例子,它可以很容易的推断到Node.JS

如果您有任何问题,请随时询问。

如果你没有问题,你的增量id中的差距,你只需要大致对应于添加行的顺序,你可以推出自己的:创build一个名为NextIdTable单独的表,一个主键(数字),称之为计数器。

每次你想要生成一个新的ID,你会做到以下几点:

  • 在NextIdTable上执行GetItem来读取Counter – > curValue的当前值
  • 在NextIdTable上执行PutItem将Counter的值设置为curValue + 1.使其成为有条件的PutItem,这样如果Counter的值发生改变,它将会失败。
  • 如果这个有条件的PutItem失败了,就意味着别人正在和你同时这么做。 重来。
  • 如果成功了,那么curValue就是你的新唯一ID。

当然,如果你的程序在实际应用到任何地方之前崩溃,你会“泄漏”它,并且在你的ID序列中有一个空白。 如果你和其他一些进程同时进行,你们其中一个会得到价值39,其中一个会得到价值40,并且不能保证你的数据表中实际应用的顺序是什么; 那个得了40的家伙可能会在39岁的家伙面前写下来。但是这确实给了你一个粗略的sorting。

这里详细介绍node.js中的条件PutItem的参数。 http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/frames.html#!AWS/DynamoDB.html 。 如果您之前已经从计数器读取38的值,则您的条件PutItem请求可能如下所示。

 var conditionalPutParams = { TableName: 'NextIdTable', Item: { Counter: { N: '39' } }, Expected: { Counter: { AttributeValueList: [ { N: '38' } ], ComparisonOperator: 'EQ' } } }; 

我不相信这是可能的SQL样式自动增量,因为表跨多个机器分区。 我在PHP中生成我自己的UUID来完成这项工作,我相信你可以在javascript中提出类似的东西。

我也遇到了同样的问题,并为此创build了一个小型Web服务。 看到这个博客文章,解释了如何使用stateful.co与DynamoDB来模拟自动递增function: http ://www.yegor256.com/2014/05/18/cloud-autoincrement-counters.html

基本上,你在stateful.co上注册一个primefaces计数器,每当你需要一个新的值,通过RESTful API增加它。 该服务是免费的。

创build新的file.js并把这个代码:

 exports.guid = function () { function _p8(s) { var p = (Math.random().toString(16)+"000000000").substr(2,8); return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ; } return (_p8() + _p8(true) + _p8(true)+new Date().toISOString().slice(0,10)).replace(/-/g,""); } 

然后你可以将这个函数应用到主键ID。 它会生成UUID。

除了@ yadutaf的回答

AWS支持primefaces计数器 。

创build一个单独的表( order_id ),其中一行保存最后的id(order_number):

 +----+--------------+ | id | order_number | +----+--------------+ | 0 | 5000 | +----+--------------+ 

将允许增加1 order_number并获得递增的结果在callback中:

 config={ region: 'us-east-1', endpoint: "http://localhost:8000" }; const docClient = new AWS.DynamoDB.DocumentClient(config); let param = { TableName: 'order_id', Key: { "id": 0 }, UpdateExpression: "set order_number = order_number + :val", ExpressionAttributeValues:{ ":val": 1 }, ReturnValues: "UPDATED_NEW" }; docClient.update(params, function(err, data) { if (err) { console.log("Unable to update the table. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log(data); console.log(data.Attributes.order_number); // <= here is our incremented result } }); 

请注意,在极less数情况下,它们可能是您的调用者点和AWS API之间的连接问题。 这将导致dynamodb行增量,而您将得到一个连接错误,并不会意识到一个新的值。 所以可能会出现less量未使用的增量值。

然后,您可以在表中使用递增的data.Attributes.order_number ,例如将{id: data.Attributes.order_number, otherfields:{}}插入到order表中。

另一种方法是为主键使用UUID生成器,因为这些不太可能发生冲突。

IMO更有可能遇到整合高可用性DynamoDB表中的主键计数的错误,而不是生成的UUID的冲突。

例如,在节点:

npm install uuid

 var uuid = require('uuid'); // Generate a v1 (time-based) id uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' // Generate a v4 (random) id uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' 

从SO 回答 。