web-dev-qa-db-fra.com

Comment utiliser l'incrémentation automatique pour l'ID de clé primaire dans dynamodb

Je suis nouveau à dynamodb. Je veux incrémenter automatiquement la valeur de l'ID lorsque j'utilise putitem avec dynamodb.

Est-ce possible de faire ça?

48
pranay

DynamoDB ne fournit pas cela immédiatement. Vous pouvez générer dans votre application des éléments tels que des UUID qui "devraient" être suffisamment uniques pour la plupart des systèmes.

J'ai remarqué que vous utilisiez Node.js (j'ai enlevé votre tag). Voici une bibliothèque qui fournit la fonctionnalité UUID: node-uuid

Exemple de 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();
43
tier1

Ceci est anti-pattern dans DynamoDB, qui est construit pour s’adapter à de nombreuses partitions/partitions/serveurs. DynamoDB ne prend pas en charge les clés primaires à incrémentation automatique en raison de limitations d’échelle et ne peut pas être garanti sur plusieurs serveurs.

La meilleure option consiste à assembler une clé primaire à partir de plusieurs index. La clé primaire peut contenir jusqu'à 2048 octets. Il y a peu d'options:

  1. Utilisez [~ # ~] uuid [~ # ~] comme clé - éventuellement un UUID temporel qui le rend unique, uniformément distribué et dont la valeur temporelle
  2. Utilisez un nombre ou un horodatage généré de manière aléatoire + aléatoire (éventuellement avec décalage de bits), comme: ts << 12 + random_number
  3. Utiliser un autre service ou DynamoDB lui-même pour générer un identifiant unique incrémental (nécessite un appel supplémentaire)

Le code suivant augmentera automatiquement le compteur dans DynamoDB et vous pourrez ensuite l’utiliser comme clé primaire.

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

Mon favori personnel utilise timestamp + random inspiré par la génération d'identifiants Sharding de Instagram à l'adresse http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram

La fonction suivante générera un identifiant pour un fragment spécifique (fourni en tant que paramètre). De cette façon, vous pouvez avoir une clé unique, qui est assemblée à partir de timestamp, shard no. et un peu de hasard (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"
34
vladaman