[英]How to use auto increment for primary key id in dynamodb
我是 dynamodb 的新手。 當我將putitem
與 dynamodb 一起使用時,我想自動增加 id 值。
有可能這樣做嗎?
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
我個人最喜歡的是在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;
}
var newPrimaryHashKey = "obj_name:" + generateRowId(4);
// output is: "obj_name:8055517407349240"
您可能可以使用AtomicCounters 。
使用 AtomicCounters,您可以使用 UpdateItem 操作來實現原子計數器 - 一個無條件遞增的數字屬性,不會干擾其他寫入請求。 (所有寫請求都按照收到的順序應用。)使用原子計數器,更新不是冪等的。 換句話說,每次調用 UpdateItem 時,數值都會增加。
您可以使用原子計數器來跟蹤網站訪問者的數量。 在這種情況下,您的應用程序將增加一個數值,而不管其當前值如何。 如果 UpdateItem 操作失敗,應用程序可以簡單地重試該操作。 這可能會冒兩次更新計數器的風險,但您可能可以容忍網站訪問者的輕微多計數或少計數。
遇到了類似的問題,我需要在我的表中自動增加主鍵。 我們可以使用一些隨機化技術來生成一個隨機密鑰並使用它來存儲它。 但它不會以增量方式進行。
如果您需要一些增量方式,您可以使用Unix Time作為您的主鍵。 不能保證您可以獲得准確的增量(一個一個),但是是的,您放置的每條記錄都是增量方式,這與插入每條記錄的時間不同。
不是一個完整的解決方案,如果您不想讀取整個表並獲取它的最后一個id
然后增加它。
以下是使用 NodeJS 在 DynamoDB 中插入記錄的代碼:
.
.
const params = {
TableName: RANDOM_TABLE,
Item: {
ip: this.ip,
id: new Date().getTime()
}
}
dynamoDb.put(params, (error, result) => {
console.log(error, result);
});
.
.
如果您使用 NoSQL Dynamo DB 然后使用 Dynamoose,您可以輕松設置默認唯一 ID,這是簡單的用戶創建示例
// 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);
};
對於 Java 開發人員,有DynamoDBMapper ,它是一個簡單的 ORM。它支持DynamoDBAutoGeneratedKey注釋。 它不會像典型的“Long id”那樣增加數值,而是像此處建議的其他答案一樣生成 UUID。 如果您像使用 Hibernate、GORM 等一樣映射類,則代碼更少會更自然。
我在文檔中沒有看到關於縮放問題的警告。 並且它消除了與自動遞增的數值(文檔確實指出)一樣的計數不足或過多的問題。
2022 年更新:
我正在尋找同樣的問題,並遇到了以下研究。
DynamoDB 仍然不支持主鍵的自動遞增。
https:\/\/aws.amazon.com\/blogs\/database\/simulating-amazon-dynamodb-unique-constraints-using-transactions\/<\/a>
此外,包node-uuid<\/a>現在已被棄用。 他們建議我們使用uuid<\/a>包來創建符合 RFC4122 的 UUID。
npm install uuid
import { v4 as uuidv4 } from 'uuid';
uuidv4(); // ⇨ '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.