Tüm cevaplar (bu yazının yazıldığı sırada), Redis, MongoDB ve belki de SQL tabanlı ilişkisel bir veritabanının aslında aynı araç olduğunu varsayar: "veri depola". Veri modellerini hiç dikkate almazlar.
MongoDB: Karmaşık Veriler
MongoDB bir belge deposudur. SQL güdümlü ilişkisel veritabanı ile karşılaştırmak için: ilişkisel veritabanları dizinlenmiş CSV dosyalarına sadeleştirilir, her dosya bir tablodur; belge depoları, her dosya bir belge olan ve birden çok dosya birlikte gruplandırılmış olarak dizinlenmiş JSON dosyalarına sadeleştirir.
JSON dosyaları yapı olarak XML ve YAML dosyalarına ve Python'daki sözlüklere benzer, bu nedenle bu tür hiyerarşideki verilerinizi düşünün. Dizin oluştururken yapı anahtardır: Bir belge, başka belgeler, diziler veya skaler değerler içeren adlandırılmış anahtarlar içerir. Aşağıdaki dokümanı düşünün.
{
_id: 0x194f38dc491a,
Name: "John Smith",
PhoneNumber:
Home: "555 999-1234",
Work: "555 999-9876",
Mobile: "555 634-5789"
Accounts:
- "379-1111"
- "379-2574"
- "414-6731"
}
Yukarıdaki belgenin PhoneNumber.Mobile
değeri olan bir anahtarı vardır 555 634-5789
. Anahtarın PhoneNumber.Mobile
bir değeri olduğu belgelerden oluşan bir koleksiyonda arama yapabilirsiniz ; dizine eklenir.
Ayrıca, Accounts
birden fazla dizini barındıran bir diziye sahiptir . Bir belge için sorgu mümkündür Accounts
içeren tam bazı değerler alt kümesi tüm değerlerin bir kısmını da, ya hiçbir değerlerin bir kısmını da. Bu Accounts = ["379-1111", "379-2574"]
, yukarıdakileri arayabileceğiniz ve bulamayacağınız anlamına gelir ; Accounts includes ["379-1111"]
yukarıdaki belgeyi arayabilir ve bulabilirsiniz; ve Accounts includes any of ["974-3785","414-6731"]
yukarıdaki bilgileri ve varsa "974-3785" hesabını içeren belgeyi arayabilir ve bulabilirsiniz.
Belgeler istediğiniz kadar derine iniyor. PhoneNumber.Mobile
bir diziyi, hatta bir alt dokümanı ( PhoneNumber.Mobile.Work
ve PhoneNumber.Mobile.Personal
) tutabilir . Verileriniz son derece yapılandırılmışsa, dokümanlar ilişkisel veritabanlarında büyük bir adımdır.
Verileriniz çoğunlukla düz, ilişkisel ve katı bir şekilde yapılandırılmışsa, ilişkisel bir veritabanıyla daha iyi durumda olursunuz. Yine, büyük işaret, veri modellerinizin birbiriyle ilişkili CSV dosyalarından oluşan bir koleksiyona mı yoksa XML / JSON / YAML dosyalarından oluşan bir koleksiyona mı ait olduğudur.
Çoğu proje için, SQL veya Document Store'ların uymadığı bazı küçük alanlarda küçük bir çözümü kabul ederek ödün vermeniz gerekir; geniş bir veri yayılımı depolayan bazı büyük, karmaşık projeler için (birçok sütun; satırlar önemsizdir), bazı verileri bir modelde ve diğer verileri başka bir modelde saklamak mantıklı olacaktır. Facebook hem SQL hem de bir grafik veritabanı kullanır (burada veriler düğümlere yerleştirilir ve düğümler diğer düğümlere bağlanır); Craigslist eskiden MySQL ve MongoDB kullanıyordu, ama tamamen MongoDB'ye geçmeye çalışıyordu. Bunlar, bir model altına konulursa verilerin kapsamı ve ilişkisinin önemli handikaplarla karşılaştığı yerlerdir.
Redis: Anahtar / Değer Değeri
Redis, temelde bir anahtar / değer deposu. Redis, ona bir anahtar vermenizi ve tek bir değer aramanızı sağlar. Redis, dizeleri, listeleri, karmaları ve diğer birkaç şeyi saklayabilir; ancak, sadece isme bakar.
Önbellek geçersiz kılma, bilgisayar biliminin zor sorunlarından biridir; diğeri bir şeyleri adlandırmak. Bu, arka uçta yüzlerce fazla aramayı önlemek istediğinizde Redis'i kullanacağınız anlamına gelir, ancak yeni bir aramaya ihtiyaç duyduğunuzda anlamanız gerekir.
En belirgin geçersiz kılma durumu yazma sırasında güncellenmesidir: Eğer okursanız user:Simon:lingots = NOTFOUND
, SELECT Lingots FROM Store s INNER JOIN UserProfile u ON s.UserID = u.UserID WHERE u.Username = Simon
sonucu 100
olarak saklayabilirsiniz SET user:Simon:lingots = 100
. Simon 5 lingots ödül Sonra, okumak user:Simon:lingots = 100
, SET user:Simon:lingots = 105
ve UPDATE Store s INNER JOIN UserProfile u ON s.UserID = u.UserID SET s.Lingots = 105 WHERE u.Username = Simon
. Artık veritabanınızda ve Redis'de 105 var ve veritabanını user:Simon:lingots
sorgulamadan alabilirsiniz .
İkinci durum bağımlı bilgileri güncellemek. Bir sayfanın parçalarını oluşturduğunuzu ve çıktılarını önbelleğe aldığınızı varsayalım. Başlık oyuncunun deneyimini, seviyesini ve para miktarını gösterir; oyuncunun Profil sayfasında istatistiklerini gösteren bir blok bulunur; ve benzerleri. Oyuncu biraz tecrübe kazanır. Eh, şimdi birkaç var templates:Header:Simon
, templates:StatsBox:Simon
, templates:GrowthGraph:Simon
sorguları bir şablon motoru aracılığıyla çalıştırmak yarım düzine veritabanının çıkışını önbelleğe ettik nerede ve benzeri alanlar. Normalde, bu sayfaları görüntülediğinizde şunları söylersiniz:
$t = GetStringFromRedis("templates:StatsBox:" + $playerName);
if ($t == null) {
$t = BuildTemplate("StatsBox.tmpl",
GetStatsFromDatabase($playerName));
SetStringInRedis("Templates:StatsBox:" + $playerName, $t);
}
print $t;
Sonuçlarını yeni güncellediğiniz için anahtar / değer önbelleğinizi GetStatsFromDatabase("Simon")
bırakmanız gerekir templates:*:Simon
. Bu şablonlardan herhangi birini oluşturmaya çalıştığınızda, uygulamanız veri tabanınızdan (PostgreSQL, MongoDB) veri alıp şablonunuza ekleyecek; sonucu Redis'te saklar ve umarım, bir sonraki çıkış bloğunu görüntülediğinde veritabanı sorguları yapma ve şablonlar oluşturma zahmetine girmez.
Redis ayrıca yayıncı-abone mesaj kuyrukları vb. Yapmanızı sağlar. Bu tamamen başka bir konu. Burada nokta Redis, ilişkisel bir veritabanından veya bir belge deposundan farklı bir anahtar / değer önbelleğidir.
Sonuç
İhtiyaçlarınıza göre araçlarınızı seçin. En büyük ihtiyaç genellikle veri modelidir, çünkü kodunuzun ne kadar karmaşık ve hataya açık olduğunu belirler. Özel uygulamalar performansa, her şeyi C ve Assembly karışımına yazdığınız yerlere dayanacaktır; çoğu uygulama genelleştirilmiş durumu ele alır ve yüksek performanslı bir SQL veritabanından veya bir belge deposundan çok daha hızlı olan Redis veya Memcached gibi bir önbellek sistemi kullanır.