Я новачок у dynamodb. Я хочу автоматично збільшити значення ідентифікатора, коли я використовую putitem
з dynamodb.
Чи можна це зробити?
Я новачок у dynamodb. Я хочу автоматично збільшити значення ідентифікатора, коли я використовую putitem
з dynamodb.
Чи можна це зробити?
Відповіді:
DynamoDB не надає цього нестандартно. Ви можете створити щось у своєму додатку, наприклад UUID, що "повинно" бути досить унікальним для більшості систем.
Я помітив, що ви використовуєте 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();
Це анти-шаблон у DynamoDB, який будується для масштабування на багатьох розділах / осколках / серверах. DynamoDB не підтримує автоматичне збільшення первинних ключів через обмеження масштабування і не може бути гарантована на декількох серверах.
Кращим варіантом є складання первинного ключа з декількох індексів. Первинний ключ може мати до 2048 байт. Варіантів небагато:
Наступний код автоматично збільшить лічильник у 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
Моїм улюбленим є використання позначки часу + випадковий натхнення від генерації ідентифікаторів Sharding ID за адресою http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram
Наступна функція згенерує ідентифікатор для конкретного осколка (надається як параметр). Таким чином, ви можете отримати унікальний ключ, який збирається з позначки часу, номер шранда. і деяка випадковість (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;
}
var newPrimaryHashKey = "obj_name:" + generateRowId(4);
// output is: "obj_name:8055517407349240"
subId
повинен бути ідентифікатор осколка чи щось інше?
var randid = Math.floor(Math.random() * 512); ... randid % 512
слід вказати число від 0 до 511 у першому рядку. Використання модуля 512 для такого числа не змінює число.
Можливо, ви можете використовувати AtomicCounters .
За допомогою AtomicCounters ви можете використовувати операцію UpdateItem для реалізації атомного лічильника - числового атрибута, який збільшується, безумовно, без втручання в інші запити на запис. (Усі запити на запис застосовуються в тому порядку, в якому вони були отримані.) За допомогою атомного лічильника оновлення не є ідемпотентними. Іншими словами, числове значення збільшується кожного разу, коли ви викликаєте UpdateItem.
Ви можете використовувати атомний лічильник для відстеження кількості відвідувачів веб-сайту. У цьому випадку ваш додаток збільшить числове значення, незалежно від його поточного значення. Якщо операція UpdateItem не вдається, програма може просто повторити спробу. Це може загрожувати оновлення лічильника двічі, але ви, мабуть, можете допустити незначний перерахунок або недолік відвідувачів веб-сайту.
Якщо ви використовуєте NoSQL Dynamo DB, то, використовуючи Dynamoose, ви можете легко встановити унікальний ідентифікатор за замовчуванням, ось простий приклад створення користувача
// User.modal.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;
// User.controller.js
exports.create = async (req, res) => {
const user = new User({ id: uuidv4(), ...req.body }); // set unique id
const [err, response] = await to(user.save());
if (err) {
return badRes(res, err);
}
return goodRes(res, reponse);
};
Натрапив на подібну проблему, коли я вимагав автоматичного збільшення первинного ключа в своїй таблиці. Ми могли б використовувати деякі методи рандомізації, щоб створити випадковий ключ і зберегти його, використовуючи це. Але це не буде поступовим способом.
Якщо вам потрібно щось поступово, ви можете використовувати Unix Time як свій основний ключ. Не впевнений, що ви можете отримати точний приріст (по одному), але так, кожен запис, який ви ставите, був би поступовим щодо різниці в тому, скільки часу кожен запис вставлений.
Не повне рішення, якщо ви не хочете читати всю таблицю і отримувати її останньою, id
а потім збільшувати її.
Нижче наведено код для вставки запису в DynamoDB за допомогою NodeJS:
.
.
const params = {
TableName: RANDOM_TABLE,
Item: {
ip: this.ip,
id: new Date().getTime()
}
}
dynamoDb.put(params, (error, result) => {
console.log(error, result);
});
.
.