Güzel soru, ben de bununla ilgileniyordum.
Her değişiklikte yeni bir sürüm oluşturun
Ruby için Mongoid sürücüsünün Sürüm Oluşturma modülüne rastladım . Kendim kullanmadım, ancak bulabildiğim kadarıyla her belgeye bir sürüm numarası ekliyor. Daha eski sürümler belgenin kendisinde gömülüdür. En büyük dezavantajı, her değişiklikte tüm belgenin kopyalanmasıdır ; bu, büyük belgelerle uğraşırken çok sayıda yinelenen içeriğin depolanmasına neden olur. Bu yaklaşım, küçük boyutlu belgelerle uğraşırken ve / veya belgeleri çok sık güncellemediğinizde iyidir.
Değişiklikleri yalnızca yeni bir sürümde saklayın
Başka bir yaklaşım, yeni bir sürümde yalnızca değiştirilen alanları depolamak olacaktır . Ardından, belgenin herhangi bir sürümünü yeniden oluşturmak için geçmişinizi 'düzleştirebilirsiniz'. Modelinizdeki değişiklikleri izlemeniz ve güncellemeleri ve silmeleri, uygulamanızın güncel belgeyi yeniden yapılandırabileceği şekilde depolamanız gerektiğinden, bu oldukça karmaşıktır. Düz SQL tabloları yerine yapılandırılmış belgelerle uğraştığınız için bu biraz yanıltıcı olabilir.
Belgede değişiklikleri saklayın
Her alanın ayrıca ayrı bir geçmişi olabilir. Belgeleri belirli bir sürüme yeniden yapılandırmak bu şekilde çok daha kolaydır. Uygulamanızda değişiklikleri açıkça izlemeniz gerekmez, ancak değerini değiştirdiğinizde mülkün yeni bir sürümünü oluşturmanız yeterlidir. Bir belge şunun gibi görünebilir:
{
_id: "4c6b9456f61f000000007ba6"
title: [
{ version: 1, value: "Hello world" },
{ version: 6, value: "Foo" }
],
body: [
{ version: 1, value: "Is this thing on?" },
{ version: 2, value: "What should I write?" },
{ version: 6, value: "This is the new body" }
],
tags: [
{ version: 1, value: [ "test", "trivial" ] },
{ version: 6, value: [ "foo", "test" ] }
],
comments: [
{
author: "joe", // Unversioned field
body: [
{ version: 3, value: "Something cool" }
]
},
{
author: "xxx",
body: [
{ version: 4, value: "Spam" },
{ version: 5, deleted: true }
]
},
{
author: "jim",
body: [
{ version: 7, value: "Not bad" },
{ version: 8, value: "Not bad at all" }
]
}
]
}
Bir sürümde belgenin bir bölümünü silinmiş olarak işaretlemek yine de biraz garip. state
Uygulamanızdan silinebilecek / geri yüklenebilecek parçalar için bir alan tanıtabilirsiniz :
{
author: "xxx",
body: [
{ version: 4, value: "Spam" }
],
state: [
{ version: 4, deleted: false },
{ version: 5, deleted: true }
]
}
Bu yaklaşımların her biri ile güncel ve düzleştirilmiş bir sürümü tek bir koleksiyonda ve geçmiş verilerini ayrı bir koleksiyonda depolayabilirsiniz. Bu, yalnızca bir belgenin son sürümüyle ilgileniyorsanız, sorgu sürelerini iyileştirmelidir. Ancak hem en son sürüme hem de geçmiş verilere ihtiyacınız olduğunda, bir yerine iki sorgu gerçekleştirmeniz gerekir. Dolayısıyla, iki ayrı koleksiyon yerine tek bir koleksiyon kullanma seçimi, uygulamanızın geçmiş sürümlere ne sıklıkla ihtiyaç duyduğuna bağlı olmalıdır .
Bu cevabın çoğu düşüncelerimin beyin dökümüdür, aslında bunların hiçbirini henüz denemedim. Geriye dönüp baktığımızda, yinelenen verilerin ek yükü uygulamanız için çok önemli olmadığı sürece, ilk seçenek muhtemelen en kolay ve en iyi çözümdür. İkinci seçenek oldukça karmaşıktır ve muhtemelen çabaya değmez. Üçüncü seçenek temelde ikinci seçeneğin bir optimizasyonudur ve uygulaması daha kolay olmalıdır, ancak birinci seçeneği gerçekten uygulayamadığınız sürece muhtemelen uygulama çabasına değmez.
Bununla ilgili geri bildirimleri ve diğer kişilerin soruna yönelik çözümlerini dört gözle bekliyorum :)