web-gelistirme-sc.com

DynamoDB'de UUID nasıl yapılır?

Db programımda, kendiliğinden bir birincil anahtara ihtiyacım var. Bu özelliği nasıl anlayabilirim?

PS DynamoDB'ye erişmek için, Node.js. için dynode , modüllerini kullanıyorum.

21
NiLL

Yasal Uyarı: Ben Dynamodb-mapper projesinin sorumlusuyum

Bir otomatik artış anahtarının sezgisel iş akışı:

  1. son karşı pozisyonu al
  2. ekle 1
  3. yeni sayıyı nesnenin indeksi olarak kullanın.
  4. yeni sayaç değerini kaydet
  5. nesneyi kaydet

Bu sadece temel fikri açıklamak içindir. Asla bu şekilde yapmayın çünkü atomik değil. Belirli iş yükü altında, aynı kimliği atomik olmadığı için 2+ farklı nesneye tahsis edebilirsiniz. Bu veri kaybına neden olur.

Çözüm, atomik ADD işlemini ALL_NEW / UpdateItem ile birlikte kullanmaktır:

  1. atomik olarak bir kimlik üret
  2. yeni sayıyı nesnenin indeksi olarak kullanın.
  3. nesneyi kaydet

En kötü senaryoda, nesne kaydedilmeden önce uygulama çöker ancak aynı kimliği iki kez atama riski yoktur.

Kalan bir sorun var: Son ID değerinin nerede saklanması gerekiyor? Seçtik:

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

Elbette, güvenilir bir şekilde çalışmak için, veri ekleyen tüm uygulamaların bu sistemden haberdar olması GEREKLİDİR, aksi halde verilerin üzerine yazabilirsiniz.

son adım süreci otomatikleştirmek. Örneğin: 

When hash_key is 0:
    atomically_allocate_ID()
actual_save()

Uygulama detayları için (Python, üzgünüm), https://bitbucket.org/Ludia/dynamodb-mapper/src/8173d0e8b55d/dynamodb_mapper/src/8173d0e8b55d/dynamodb_mapper/model.py#cl-67

Doğruyu söylemek gerekirse, şirketim üretimde kullanmıyor, çünkü çoğu zaman, kullanıcı için bir kimlik, bir işlem için, bir tarih, vb. Gibi başka bir anahtar bulmak daha iyidir.

Bazı örnekleri dynamodb-mapper'ın belgelerinin 'sinde yazdım ve kolayca Node.JS'ye tahmin edilebilir.

Herhangi bir sorunuz varsa, sormaya çekinmeyin.

19
yadutaf

Artan kimliğinizdeki boşluklarla ilgili sorunlarınız varsa ve yalnızca kabaca satırların eklendiği sıraya karşılık gelen bir sorun yoksa, kendi başınıza dönebilirsiniz: Bir birincil anahtarla, NextIdTable adlı ayrı bir tablo oluşturun ( sayısal), buna Çağrı Sayacı.

Her yeni bir kimlik oluşturmak istediğinizde, aşağıdakileri yaparsınız:

  • Counter -> curValue öğesinin geçerli değerini okumak için NextIdTable'da bir GetItem yapın
  • Sayaç değerini curValue + 1 olarak ayarlamak için NextIdTable'da bir PutItem yapın. 1. Bunu, koşullu bir PutItem yapın; böylece, Sayaç değeri değişmişse başarısız olur. 
  • Bu koşullu PutItem başarısız olursa, bu aynı anda sizin yaptığınız başka biri tarafından bunu yapıyor demektir. Baştan başlamak. 
  • Eğer başarılı olursa, curValue yeni benzersiz kimliğinizdir.

Elbette, işleminiz bu kimliği gerçekten herhangi bir yere uygulamadan önce çökerse, onu "sızdıracaksınız" ve kimlikler sıranızda bir boşluk olacaktır. Ve bunu başka bir işlemle aynı anda yapıyorsanız, biriniz 39 değerini alırsınız ve biriniz 40 değerini alırsınız ve gerçekte veri tablonuzda hangi sırayla uygulanacaklarına dair hiçbir garanti yoktur; 40 yaşında olan adam 39 yaşında olandan önce yazabilir. Ama bu size zorlu bir emirdir.

Node.js'deki koşullu bir PutItem parametresi burada ayrıntılı olarak açıklanmıştır. http://docs.aws.Amazon.com/AWSJavaScriptSDK/latest/frames.html#!AWS/DynamoDB.html . Daha önce Counter'dan 38 değerini okumuş olsaydınız, koşullu PutItem isteğiniz böyle görünebilirdi.

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

Diğer bir yaklaşım, birincil anahtarlar için UUID oluşturucuyu kullanmaktır, çünkü bunlar highly çarpışma olasılığı düşüktür. 

IMO, birincil anahtar sayaçlarını yüksek kullanılabilir DynamoDB tablolarında birleştirerek oluşturulan UUIDs öğesindeki çakışmalardan daha fazla hatayla karşılaşmanız daha olasıdır.

Örneğin, Düğümde:

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 answer konumundan alınmıştır.

4
James

@ yadutaf'ın cevabına ekleme

AWS, Atom Sayıcıları öğesini destekler.

En son order_number değerini tutan bir satır ile ayrı bir tablo (order_id) oluşturun:

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

Bu, order_number değerini 1 ile artırmaya ve AWS DynamoDB'den geri aramada artan sonucu elde etmenize olanak sağlar:

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

???? Bazı nadir durumlarda bunların arayan noktanız ile AWS API arasındaki bağlantıda sorun olabileceğini unutmayın. Bir bağlantı hatası alırken, dinamodb satırının artmasıyla sonuçlanacaktır. Bu nedenle, kullanılmayan artımlı değerler görünebilir.

Masanızda, artımlı data.Attributes.order_number kullanabilirsiniz, ör. {id: data.Attributes.order_number, otherfields:{}}order tablosuna eklemek için.

3
Artru

Tablolar birden fazla makineye bölündüğünden, SQL stili otomatik artış için mümkün olduğuna inanmıyorum. İşimi yapan PHP içinde kendi UUID'imi oluşturuyorum, benzer bir şey bulabileceğinizden eminim bu şekilde javascript'te. 

3
greg

Java’da kodlayanlar için, DynamoDBMapper şimdi sizin adınıza benzersiz UUID'ler oluşturabilir.

DynamoDBAutoGeneratedKey

Bir bölüm anahtarı veya sıralama anahtarı özelliğini otomatik olarak oluşturulmuş olarak işaretler. DynamoDBMapper bu Niteliklerini kaydederken rasgele bir UUID oluşturur. Yalnızca String özellikleri otomatik olarak oluşturulan Tuşları olarak işaretlenebilir.

Bunun gibi DynamoDBAutoGeneratedKey notunu kullanın

@DynamoDBTable(tableName="AutoGeneratedKeysExample")
public class AutoGeneratedKeys { 
    private String id;

    @DynamoDBHashKey(attributeName = "Id")
    @DynamoDBAutoGeneratedKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; } 

Yukarıdaki örnekte görebileceğiniz gibi, benzersiz bir karma anahtarı oluşturmak için hem DynamoDBAutoGeneratedKey hem de DynamoDBHashKey ek notunu aynı özelliğe uygulayabilirsiniz.

3
Stu

Aynı problemi yaşadım ve sadece bu amaç için küçük bir web servisi yarattım. Otomatik artış işlevini simüle etmek için stateful.co ile DynamoDB'yi nasıl kullandığımı açıklayan bu blog gönderisine bakın: http://www.yegor256.com/2014/05/18/cloud- autoincrement-counters.html

Temel olarak, stateful.co adresinde bir atom sayacını kaydedersiniz ve RESTful API ile her yeni değere ihtiyacınız olduğunda artırırsınız. Servis ücretsizdir.

2
yegor256

Yeni file.js dosyasını oluşturun ve bu kodu yazın:

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,"");
}

Sonra bu işlevi birincil anahtar kimliğine uygulayabilirsiniz. UUID'yi üretecektir.

0
Jivi

Otomatik Artış, diğerlerini boşta tutarken belirli parçaları aşırı yükleyeceğinden performans açısından iyi değildir, Dynamodb'a veri depolarsanız bile dağıtım yapmaz.

awsRequestId aslında V.4 UUID (Random), denemek için aşağıdaki kod parçacığına benziyor:

exports.handler = function(event, context, callback) {
    console.log('remaining time =', context.getRemainingTimeInMillis());
    console.log('functionName =', context.functionName);
    console.log('AWSrequestID =', context.awsRequestId);
    callback(null, context.functionName);
};

Bunu kendiniz oluşturmak isterseniz, aşağıdakilere dayanarak farklı UUID sürümleri oluşturmak için https://www.npmjs.com/package/uuid veya lide 'i kullanabilirsiniz. RFC-4122

  • V1 (zaman damgası tabanlı)
  • V3 (Ad alanı)
  • V4 (Rastgele)

Go geliştiricileri için bu paketleri Google’ın UUID , Pborman veya Satori adresinden kullanabilirsiniz. Pborman performansta daha iyidir, daha fazla ayrıntı için şunları kontrol edin makaleler ve kıyaslamalar .

Evrensel Eşsiz Tanımlayıcı Özelliği Hakkında Daha Fazla Bilgi Bulunamadı burada .

0
Muhammad Soliman