Önceki modülde, tablonuza bir ters dizin eklediniz. Ters dizin, ilişkisel veriler için ek sorgu kalıpları ekler. Ancak hâlâ bir sorunumuz olduğunu gördük. Belirli bir Kullanıcı varlığı için tüm Arkadaşlık varlıklarını sorgulayabilmemize rağmen, Arkadaşlık varlığı izlenen kullanıcı hakkında bilgi içermez.

Bu modülde kısmi normalleştirme hakkında bilgi edineceksiniz.

İkinci modülde, DynamoDB ile modelleme yaparken ilişkisel bir model taklit etmeye çalışmamanız gerektiğini gördük. İlişkisel modelin temel noktalarından biri, verileri birden çok yerde çoğaltmaktan kaçındığınız verilerin normalleştirilmesidir. Normalleştirme, ilişkisel veritabanlarında iyi bir şablondur. Ancak, sorgulama yaparken verilerinizi yeniden birleştirmek için pahalı birleşimler gerekebilir.

DynamoDB ile verilerinizi genellikle denormalize etmek istersiniz. Denormalizasyon, birleşimleri önlemeye ve sorgu performansını iyileştirmeye yardımcı olur. Bunu yapmak için, bir sorgu sırasında her iki öğenin getirilmesini önlemek amacıyla nitelikleri bir öğeden başka bir öğeye referans olarak kopyalayabilirsiniz.

Ancak, denormalizasyonun veri modelinizi karmaşıklaştırabileceği durumlar da söz konusudur. Örneğin, veri modelinde hem takip edilen hem de takip eden bir kullanıcıyı ifade eden bir Arkadaşlık varlığı vardır. Arkadaşlık varlığını oluştururken, her bir Kullanıcı varlığının tüm niteliklerini Arkadaşlık varlığına kopyalayabilirsiniz. Ardından, Arkadaşlık varlığını aldığınızda, aynı zamanda her iki kullanıcıyla ilgili tüm ayrıntılara da sahip olursunuz.

Bir kullanıcı, profilindeki bilgileri her değiştirdiğinde bu bir soruna neden olabilir. Örneğin; bir kullanıcı, profil resmini değiştirirse, o kullanıcıyı içeren her bir Arkadaşlık varlığındaki veriler bozulur. Bir güncelleme olduğunda, kullanıcıyı içeren her bir Arkadaşlık varlığını güncellemeniz gerekir.

Aşağıdaki adımlarda, bu durumu ele almak için kısmi normalleştirmenin ve BatchGetItem API çağrısının nasıl kullanılacağını göreceksiniz.

Modülü Tamamlama Süresi: 20 Dakika


  • Adım 1: İzlenen kullanıcıları bulmak için kısmi normalleştirmeyi kullanın

    Bu adımda, izlenen kullanıcıları nasıl bulacağınızı göreceksiniz. Bunlar, uygulamanızda belirli bir kullanıcı tarafından izlenen kullanıcılardır. Ayrıca, izlenen kullanıcılar hakkındaki tüm verilerin nasıl alınacağını da göreceksiniz.

    Bu modülün girişinde belirtildiği gibi, arkadaşlıklar ve kullanıcılar çerçevesinde kısmi normalleştirme tekniğini kullanmak isteyebilirsiniz. Her bir kullanıcı hakkındaki tüm bilgileri Arkadaşlık varlığında depolamak yerine, bir Arkadaşlık varlığındaki bir kullanıcı hakkında bilgi almak için BatchGetItem API'sini kullanabilirsiniz.

    İndirmiş olduğunuz kodda, find_and_enrich_following_for_user.py olarak adlandırılan application/ dizin içinde bir dosya var. Bu betiğin içerikleri aşağıda gösterilmektedir.

    import boto3
    
    from entities import User
    
    dynamodb = boto3.client('dynamodb')
    
    USERNAME = "haroldwatkins"
    
    
    def find_and_enrich_following_for_user(username):
        friend_value = "#FRIEND#{}".format(username)
        resp = dynamodb.query(
            TableName='quick-photos',
            IndexName='InvertedIndex',
            KeyConditionExpression="SK = :sk",
            ExpressionAttributeValues={":sk": {"S": friend_value}},
            ScanIndexForward=True
        )
    
        keys = [
            {
                "PK": {"S": "USER#{}".format(item["followedUser"]["S"])},
                "SK": {"S": "#METADATA#{}".format(item["followedUser"]["S"])},
            }
            for item in resp["Items"]
        ]
    
        friends = dynamodb.batch_get_item(
            RequestItems={
                "quick-photos": {
                    "Keys": keys
                }
            }
        )
    
        enriched_friends =  [User(item) for item in friends['Responses']['quick-photos']]
    
        return enriched_friends
    
    
    
    follows = find_and_enrich_following_for_user(USERNAME)
    
    print("Users followed by {}:".format(USERNAME))
    for follow in follows:
        print(follow)

    find_and_enrich_following_for_user fonksiyonu, son modülde kullandığınız find_follower_for_user fonksiyonuna benzer. Fonkisyon, izlenen kullanıcıları bulmak istediğiniz kullanıcı adını kabul eder. Fonksiyon öncelikle belirtilen kullanıcı adının takip ettiği tüm kullanıcıları bulmak için ters dizini kullanarak bir Sorgu isteği yapar. Ardından, izlenen kullanıcıların her biri için tam Kullanıcı varlığını getirmek üzere bir BatchGetItem oluşturur ve bu varlıkları iade eder.

    Bu, DynamoDB'ye yönelik bir ideal istek yerine iki istekle sonuçlanır. Ancak, bu, oldukça karmaşık bir erişim kalıbı açısından tatmin edicidir ve bir kullanıcı profili her güncellendiğinde Arkadaşlık varlıklarını sürekli olarak güncelleme ihtiyacını ortadan kaldırır. Bu kısmi normalleştirme, modelleme ihtiyaçlarınız için harika bir araç olabilir.

    Betiği aşağıdaki komutu terminalinizde çalıştırarak yürütün.

    python application/find_and_enrich_following_for_user.py

    Konsolunuz, girilen bir kullanıcı adını takiben bir kullanıcı listesi vermelidir.

    Users followed by haroldwatkins:
    User<ppierce -- Ernest Mccarty>
    User<vpadilla -- Jonathan Scott>
    User<david25 -- Abigail Alvarez>
    User<jacksonjason -- John Perry>
    User<chasevang -- Leah Miller>
    User<frankhall -- Stephanie Fisher>
    User<nmitchell -- Amanda Green>
    User<tmartinez -- Kristin Stevens>
    User<natasha87 -- Walter Carlson>
    User<geoffrey32 -- Mary Martin>
    

    Artık, Arkadaşlık varlıkları yerine Kullanıcı varlıkları ile uğraştığınızı unutmayın. Kullanıcı varlığı, kullanıcınız hakkında en eksiksiz ve güncel bilgilere sahip olacaktır. Bu noktaya ulaşmak için iki istek gerekmesine rağmen, yine de tam denormalizasyondan ve bundan kaynaklanan veri bütünlüğü sorunlarından daha iyi bir seçenek olabilir.

  • Sonuç

    Bu modülde, kısmi normalleştirmenin ve BatchGetItem API çağrısının, sorgu isteklerini düşük tutarken nesneler arasında veri bütünlüğünü korumaya nasıl yardımcı olabileceğini gördük.

    Bir sonraki modülde, bir fotoğrafa yanıt eklediğimizde veya bir kullanıcıyı izlediğimizde DynamoDB işlemlerini kullanacağız.