DocumentDB - Veri Modelleme

DocumentDB gibi şemasız veritabanları, veri modelinizdeki değişiklikleri benimsemeyi çok kolaylaştırırken, yine de verileriniz hakkında düşünmek için biraz zaman harcamalısınız.

  • Çok seçeneğiniz var. Doğal olarak, yalnızca JSON nesne grafikleri veya hatta JSON metninin ham dizeleri üzerinde çalışabilirsiniz, ancak derleme zamanında bir sınıf tanımlamadan çalışma zamanında özelliklere bağlanmanıza izin veren dinamik nesneleri de kullanabilirsiniz.

  • Ayrıca gerçek C # nesneleriyle veya çağrıldıkları şekliyle Varlıklar ile çalışabilirsiniz, bunlar iş etki alanı sınıflarınız olabilir.

İlişkiler

Belgenin hiyerarşik yapısına bir göz atalım. LastName ve isRegistered gibi gerekli id ​​gibi birkaç üst düzey özelliğe sahiptir, ancak aynı zamanda yuvalanmış özelliklere de sahiptir.

{ 
   "id": "AndersenFamily", 
   "lastName": "Andersen", 
	
   "parents": [ 
      { "firstName": "Thomas", "relationship": "father" }, 
      { "firstName": "Mary Kay", "relationship": "mother" } 
   ],
	
   "children": [ 
      { 
         "firstName": "Henriette Thaulow", 
         "gender": "female", 
         "grade": 5, 
         "pets": [ { "givenName": "Fluffy", "type": "Rabbit" } ] 
      } 
   ], 
	
   "location": { "state": "WA", "county": "King", "city": "Seattle"}, 
   "isRegistered": true 
}
  • Örneğin, parent özelliği, köşeli parantezlerle belirtildiği gibi bir JSON dizisi olarak sağlanır.

  • Bu örnekteki dizide yalnızca bir çocuk olmasına rağmen, çocuklar için de başka bir dizimiz var. Yani, bir belgede bire çok ilişkinin eşdeğerini böyle modelliyorsunuz.

  • Dizideki her öğenin basit bir değer veya başka bir karmaşık nesne, hatta başka bir dizi olabileceği dizileri kullanırsınız.

  • Yani bir ailenin birden çok ebeveyni ve birden çok çocuğu olabilir ve çocuk nesnelere bakarsanız, çocuklarla evcil hayvanlar arasındaki bire çok ilişki için iç içe geçmiş bir dizi olan bir evcil hayvan özelliğine sahip olurlar.

  • Konum özelliği için, ilgili üç özelliği, eyalet, ilçe ve şehri bir nesnede birleştiriyoruz.

  • Bir nesneyi bu şekilde gömmek, bir dizi nesneyi gömmek yerine, ilişkisel bir veritabanındaki ayrı tablolardaki iki satır arasında bire bir ilişkiye sahip olmaya benzer.

Veri Gömme

DocumentDB gibi bir belge deposundaki verileri modellemeye başladığınızda, varlıklarınızı JSON'da temsil edilen bağımsız belgeler olarak ele almaya çalışın. İlişkisel veritabanlarıyla çalışırken, verileri her zaman normalleştiririz.

  • Verilerinizi normalleştirmek, tipik olarak müşteri gibi bir varlığı alıp, iletişim bilgileri ve adresler gibi gizli veri parçalarına ayırmayı içerir.

  • Bir müşteriyi tüm iletişim bilgileri ve adresleriyle birlikte okumak için, verilerinizi çalışma zamanında etkili bir şekilde toplamak için JOINS'i kullanmanız gerekir.

Şimdi bir belge veritabanındaki bağımsız bir varlık olarak aynı verileri nasıl modelleyeceğimize bakalım.

{
   "id": "1", 
   "firstName": "Mark", 
   "lastName": "Upston", 
	
   "addresses": [ 
      {             
         "line1": "232 Main Street", 
         "line2": "Unit 1", 
         "city": "Brooklyn", 
         "state": "NY", 
         "zip": 11229
      }
   ],
	
   "contactDetails": [ 
      {"email": "[email protected]"}, 
      {"phone": "+1 356 545-86455", "extension": 5555} 
   ]
}

Gördüğünüz gibi, müşterinin tüm bilgilerinin tek bir JSON belgesine gömülü olduğu müşteri kaydını normalleştirdik.

NoSQL'de ücretsiz bir şemaya sahibiz, böylece farklı formatlarda iletişim bilgilerini ve adresleri de ekleyebilirsiniz. NoSQL'de, tek bir okuma işleminde veritabanından bir müşteri kaydını alabilirsiniz. Benzer şekilde, bir kaydın güncellenmesi de tek bir yazma işlemidir.

Net SDK kullanarak belge oluşturma adımları aşağıdadır.

Step 1- DocumentClient örneğini oluşturun. Daha sonra, myfirstdb veritabanını ve ayrıca bu özel değişken koleksiyonunda sakladığımız MyCollection koleksiyonunu sorgulayacağız, böylece sınıf boyunca erişilebilir olmasını sağlayacağız.

private static async Task CreateDocumentClient() { 
   // Create a new instance of the DocumentClient
	
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)) { 
      database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id =
         'myfirstdb'").AsEnumerable().First(); 
			
      collection = client.CreateDocumentCollectionQuery(database.CollectionsLink,
         "SELECT * FROM c WHERE c.id = 'MyCollection'").AsEnumerable().First();  
			
      await CreateDocuments(client); 
   }

}

Step 2 - CreateDocuments görevinde bazı belgeler oluşturun.

private async static Task CreateDocuments(DocumentClient client) {
   Console.WriteLine(); 
   Console.WriteLine("**** Create Documents ****"); 
   Console.WriteLine();
	
   dynamic document1Definition = new {
      name = "New Customer 1", address = new { 
         addressType = "Main Office", 
         addressLine1 = "123 Main Street", 
         location = new { 
            city = "Brooklyn", stateProvinceName = "New York"
         }, 
         postalCode = "11229", countryRegionName = "United States" 
      }, 
   };
	
   Document document1 = await CreateDocument(client, document1Definition); 
   Console.WriteLine("Created document {0} from dynamic object", document1.Id); 
   Console.WriteLine(); 
}

İlk belge bu dinamik nesneden oluşturulacaktır. Bu JSON'a benzeyebilir, ama elbette değil. Bu C # kodu ve gerçek bir .NET nesnesi oluşturuyoruz, ancak sınıf tanımı yok. Bunun yerine özellikler, nesnenin başlatılma biçiminden çıkarılır. Bu belge için bir Id özelliği sağlamadığımızı da fark edebilirsiniz.

Step 3 - Şimdi CreateDocument'e bir göz atalım ve veritabanları ve koleksiyonlar oluşturmak için gördüğümüz aynı modele benziyor.

private async static Task<Document> CreateDocument(DocumentClient client,
   object documentObject) {
   var result = await client.CreateDocumentAsync(collection.SelfLink, documentObject); 
	
   var document = result.Resource; 
   Console.WriteLine("Created new document: {0}\r\n{1}", document.Id, document); 
	
   return result; 
}

Step 4- Bu sefer CreateDocumentAsync'i çağırarak belgeyi eklemek istediğimiz koleksiyonun SelfLink'ini belirledik. Bu durumda, sistem tarafından oluşturulan özellikleriyle yeni belgeyi temsil eden bir kaynak özelliğine sahip bir yanıtı geri alıyoruz.

Aşağıdaki CreateDocuments görevinde üç belge oluşturduk.

  • İlk belgede, Belge nesnesi, SDK'da kaynaktan miras alan tanımlanmış bir sınıftır ve bu nedenle tüm ortak kaynak özelliklerine sahiptir, ancak aynı zamanda şemadan bağımsız belgenin kendisini tanımlayan dinamik özellikleri de içerir.

private async static Task CreateDocuments(DocumentClient client) {
   Console.WriteLine(); 
   Console.WriteLine("**** Create Documents ****"); 
   Console.WriteLine();
	
   dynamic document1Definition = new {
      name = "New Customer 1", address = new {
         addressType = "Main Office", 
         addressLine1 = "123 Main Street", 
         location = new {
            city = "Brooklyn", stateProvinceName = "New York" 
         }, 
         postalCode = "11229", 
         countryRegionName = "United States" 
      }, 
   };
	
   Document document1 = await CreateDocument(client, document1Definition); 
   Console.WriteLine("Created document {0} from dynamic object", document1.Id); 
   Console.WriteLine();
	
   var document2Definition = @" {
      ""name"": ""New Customer 2"", 
		
      ""address"": { 
         ""addressType"": ""Main Office"", 
         ""addressLine1"": ""123 Main Street"", 
         ""location"": { 
            ""city"": ""Brooklyn"", ""stateProvinceName"": ""New York"" 
         }, 
         ""postalCode"": ""11229"", 
         ""countryRegionName"": ""United States"" 
      } 
   }"; 
	
   Document document2 = await CreateDocument(client, document2Definition); 
   Console.WriteLine("Created document {0} from JSON string", document2.Id);
   Console.WriteLine();
	
   var document3Definition = new Customer {
      Name = "New Customer 3", 
		
      Address = new Address {
         AddressType = "Main Office", 
         AddressLine1 = "123 Main Street", 
         Location = new Location {
            City = "Brooklyn", StateProvinceName = "New York" 
         }, 
         PostalCode = "11229", 
         CountryRegionName = "United States" 
      }, 
   };
	
   Document document3 = await CreateDocument(client, document3Definition); 
   Console.WriteLine("Created document {0} from typed object", document3.Id); 
   Console.WriteLine(); 
}
  • Bu ikinci belge yalnızca ham bir JSON dizesiyle çalışır. Şimdi, dizeyi bir nesneye dönüştürmek için JavaScriptSerializer'ı kullanan CreateDocument için bir aşırı yüklemeye adım atıyoruz ve daha sonra bu, ilk belgeyi oluşturmak için kullandığımız aynı CreateDocument yöntemine aktarılıyor.

  • Üçüncü belgede, uygulamamızda tanımlanan C # Müşteri nesnesini kullandık.

Bu müşteriye bir göz atalım, bir Id ve address özelliğine sahiptir, burada adres, lokasyon dahil olmak üzere kendi özellikleri ile iç içe geçmiş bir nesne olup, yine başka bir iç içe nesnedir.

using Newtonsoft.Json; 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks;

namespace DocumentDBDemo {
 
   public class Customer { 
      [JsonProperty(PropertyName = "id")] 
      public string Id { get; set; }
      // Must be nullable, unless generating unique values for new customers on client  
      [JsonProperty(PropertyName = "name")] 
      public string Name { get; set; }  
      [JsonProperty(PropertyName = "address")] 
      public Address Address { get; set; } 
   }
	
   public class Address {
      [JsonProperty(PropertyName = "addressType")] 
      public string AddressType { get; set; }  
		
      [JsonProperty(PropertyName = "addressLine1")] 
      public string AddressLine1 { get; set; }  
		
      [JsonProperty(PropertyName = "location")] 
      public Location Location { get; set; }  
		
      [JsonProperty(PropertyName = "postalCode")] 
      public string PostalCode { get; set; }  
		
      [JsonProperty(PropertyName = "countryRegionName")] 
      public string CountryRegionName { get; set; } 
   }
	
   public class Location { 
      [JsonProperty(PropertyName = "city")] 
      public string City { get; set; }  
		
      [JsonProperty(PropertyName = "stateProvinceName")]
      public string StateProvinceName { get; set; } 
   } 
}

Ayrıca, çitin her iki tarafında da uygun kuralları sürdürmek istediğimiz için JSON özellik özniteliklerine sahibiz.

Bu yüzden, iç içe geçmiş alt nesnelerle birlikte Yeni Müşteri nesnemi oluşturuyorum ve bir kez daha CreateDocument'ı çağırıyorum. Müşteri nesnemiz bir Id özelliğine sahip olmasına rağmen, bunun için bir değer sağlamadık ve bu nedenle DocumentDB, önceki iki belgede olduğu gibi GUID'e dayalı bir tane oluşturdu.

Yukarıdaki kod derlendiğinde ve çalıştırıldığında, aşağıdaki çıktıyı alacaksınız.

**** Create Documents ****  
Created new document: 575882f0-236c-4c3d-81b9-d27780206b2c 
{ 
  "name": "New Customer 1", 
  "address": { 
    "addressType": "Main Office", 
    "addressLine1": "123 Main Street", 
    "location": { 
      "city": "Brooklyn", 
      "stateProvinceName": "New York" 
    }, 
    "postalCode": "11229", 
    "countryRegionName": "United States" 
  }, 
  "id": "575882f0-236c-4c3d-81b9-d27780206b2c", 
  "_rid": "kV5oANVXnwDGPgAAAAAAAA==", 
  "_ts": 1450037545, 
  "_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDGPgAAAAAAAA==/", 
  "_etag": "\"00006fce-0000-0000-0000-566dd1290000\"", 
  "_attachments": "attachments/" 
} 
Created document 575882f0-236c-4c3d-81b9-d27780206b2c from dynamic object  
Created new document: 8d7ad239-2148-4fab-901b-17a85d331056 
{ 
  "name": "New Customer 2", 
  "address": {
    "addressType": "Main Office", 
    "addressLine1": "123 Main Street", 
    "location": { 
      "city": "Brooklyn", 
      "stateProvinceName": "New York" 
    }, 
    "postalCode": "11229", 
    "countryRegionName": "United States" 
  }, 
  "id": "8d7ad239-2148-4fab-901b-17a85d331056", 
  "_rid": "kV5oANVXnwDHPgAAAAAAAA==", 
  "_ts": 1450037545, 
  "_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDHPgAAAAAAAA==/", 
  "_etag": "\"000070ce-0000-0000-0000-566dd1290000\"", 
  "_attachments": "attachments/" 
} 
Created document 8d7ad239-2148-4fab-901b-17a85d331056 from JSON string  
Created new document: 49f399a8-80c9-4844-ac28-cd1dee689968 
{ 
  "id": "49f399a8-80c9-4844-ac28-cd1dee689968", 
  "name": "New Customer 3", 
  "address": { 
    "addressType": "Main Office", 
    "addressLine1": "123 Main Street", 
    "location": { 
      "city": "Brooklyn", 
      "stateProvinceName": "New York" 
    }, 
    "postalCode": "11229", 
    "countryRegionName": "United States" 
  }, 
  "_rid": "kV5oANVXnwDIPgAAAAAAAA==", 
  "_ts": 1450037546, 
  "_self": "dbs/kV5oAA==/colls/kV5oANVXnwA=/docs/kV5oANVXnwDIPgAAAAAAAA==/", 
  "_etag": "\"000071ce-0000-0000-0000-566dd12a0000\"", 
  "_attachments": "attachments/" 
}
Created document 49f399a8-80c9-4844-ac28-cd1dee689968 from typed object