Bu kılavuz, veri mimarisindeki bazı temel kavramları ve JSON verilerini Firebase Gerçek Zamanlı Veritabanınızda yapılandırmaya yönelik en iyi uygulamaları kapsar.
Düzgün yapılandırılmış bir veritabanı oluşturmak, biraz öngörü gerektirir. En önemlisi, bu işlemi olabildiğince kolaylaştırmak için verilerin nasıl kaydedileceğini ve daha sonra alınacağını planlamanız gerekir.
Veriler nasıl yapılandırılır: bu bir JSON ağacıdır
Tüm Firebase Gerçek Zamanlı Veritabanı verileri, JSON nesneleri olarak depolanır. Veritabanını bulutta barındırılan bir JSON ağacı olarak düşünebilirsiniz. Bir SQL veritabanının aksine, tablo veya kayıt yoktur. JSON ağacına veri eklediğinizde, mevcut JSON yapısında ilişkilendirilmiş bir anahtarla bir düğüm haline gelir. Kullanıcı kimlikleri veya anlamsal adlar gibi kendi anahtarlarınızı veya push()
yöntemi kullanılarak sizin için sağlanabilir.
Kendi anahtarlarınızı oluşturursanız, bunlar UTF-8 kodlu olmalı, maksimum 768 bayt olabilir ve .
, $
, #
, [
, ]
, /
veya ASCII kontrol karakterleri 0-31 veya 127. ASCII kontrol karakterlerini değerlerin kendisinde de kullanamazsınız.
Örneğin, kullanıcıların temel bir profil ve kişi listesi saklamasına izin veren bir sohbet uygulamasını düşünün. Tipik bir kullanıcı profili, /users/$uid
gibi bir yolda bulunur. alovelace
kullanıcısı şuna benzeyen bir veritabanı girişine sahip olabilir:
{ "users": { "alovelace": { "name": "Ada Lovelace", "contacts": { "ghopper": true }, }, "ghopper": { ... }, "eclarke": { ... } } }
Veritabanı bir JSON ağacı kullansa da, veritabanında depolanan veriler, daha sürdürülebilir kod yazmanıza yardımcı olmak için mevcut JSON türlerine karşılık gelen belirli yerel türler olarak temsil edilebilir.
Veri yapısı için en iyi uygulamalar
İç içe geçmiş verilerden kaçının
Firebase Gerçek Zamanlı Veritabanı, verilerin 32 düzey derinliğe kadar iç içe yerleştirilmesine izin verdiğinden, bunun varsayılan yapı olması gerektiğini düşünebilirsiniz. Ancak, veritabanınızdaki bir konumdan veri getirdiğinizde, onun tüm alt düğümlerini de alırsınız. Ayrıca, veritabanınızdaki bir düğümde birine okuma veya yazma erişimi verdiğinizde, o kişiye o düğüm altındaki tüm verilere erişim izni vermiş olursunuz. Bu nedenle, pratikte, veri yapınızı olabildiğince düz tutmak en iyisidir.
İç içe geçmiş verilerin neden kötü olduğuna dair bir örnek için aşağıdaki çoklu iç içe yapıyı göz önünde bulundurun:
{ // This is a poorly nested data architecture, because iterating the children // of the "chats" node to get a list of conversation titles requires // potentially downloading hundreds of megabytes of messages "chats": { "one": { "title": "Historical Tech Pioneers", "messages": { "m1": { "sender": "ghopper", "message": "Relay malfunction found. Cause: moth." }, "m2": { ... }, // a very long list of messages } }, "two": { ... } } }
Bu iç içe tasarımla, verilerin yinelenmesi sorunlu hale gelir. Örneğin, sohbet konuşmalarının başlıklarının listelenmesi, tüm üyeler ve mesajlar da dahil olmak üzere tüm chats
ağacının istemciye indirilmesini gerektirir.
Veri yapılarını düzleştirme
Veriler bunun yerine normalden arındırma olarak da adlandırılan ayrı yollara bölünürse, gerektiğinde ayrı aramalarda verimli bir şekilde indirilebilir. Bu düzleştirilmiş yapıyı düşünün:
{ // Chats contains only meta info about each conversation // stored under the chats's unique ID "chats": { "one": { "title": "Historical Tech Pioneers", "lastMessage": "ghopper: Relay malfunction found. Cause: moth.", "timestamp": 1459361875666 }, "two": { ... }, "three": { ... } }, // Conversation members are easily accessible // and stored by chat conversation ID "members": { // we'll talk about indices like this below "one": { "ghopper": true, "alovelace": true, "eclarke": true }, "two": { ... }, "three": { ... } }, // Messages are separate from data we may want to iterate quickly // but still easily paginated and queried, and organized by chat // conversation ID "messages": { "one": { "m1": { "name": "eclarke", "message": "The relay seems to be malfunctioning.", "timestamp": 1459361875337 }, "m2": { ... }, "m3": { ... } }, "two": { ... }, "three": { ... } } }
Artık görüşme başına yalnızca birkaç bayt indirerek, odaları bir kullanıcı arabiriminde listelemek veya görüntülemek için meta verileri hızlı bir şekilde getirerek oda listesinde yineleme yapmak mümkün. Mesajlar ayrı olarak alınabilir ve geldiklerinde görüntülenebilir, bu da kullanıcı arayüzünün duyarlı ve hızlı kalmasına olanak tanır.
Ölçeklenen veriler oluşturun
Uygulama oluştururken genellikle bir listenin alt kümesini indirmek daha iyidir. Liste binlerce kayıt içeriyorsa bu özellikle yaygındır. Bu ilişki statik ve tek yönlü olduğunda, alt nesneleri üst öğenin altına yerleştirebilirsiniz.
Bazen bu ilişki daha dinamiktir veya bu veriyi denormalize etmek gerekebilir. Verileri Al bölümünde açıklandığı gibi, çoğu zaman verilerin bir alt kümesini almak için bir sorgu kullanarak verileri normallikten kurtarabilirsiniz.
Ama bu bile yetersiz kalabilir. Örneğin, kullanıcılar ve gruplar arasında iki yönlü bir ilişki düşünün. Kullanıcılar bir gruba ait olabilir ve gruplar bir kullanıcı listesinden oluşur. Bir kullanıcının hangi gruplara ait olduğuna karar verme zamanı geldiğinde işler karmaşıklaşıyor.
İhtiyaç duyulan şey, bir kullanıcının ait olduğu grupları listelemenin ve yalnızca bu gruplar için verileri getirmenin zarif bir yoludur. Bir grup dizini burada çok yardımcı olabilir:
// An index to track Ada's memberships { "users": { "alovelace": { "name": "Ada Lovelace", // Index Ada's groups in her profile "groups": { // the value here doesn't matter, just that the key exists "techpioneers": true, "womentechmakers": true } }, ... }, "groups": { "techpioneers": { "name": "Historical Tech Pioneers", "members": { "alovelace": true, "ghopper": true, "eclarke": true } }, ... } }
Bunun, ilişkiyi hem Ada'nın kaydı hem de grup altında saklayarak bazı verileri çoğalttığını fark edebilirsiniz. Artık alovelace
bir grup altında indeksleniyor ve techpioneers
Ada'nın profilinde listeleniyor. Yani Ada'yı gruptan silmek için iki yerde güncellenmesi gerekiyor.
Bu, iki yönlü ilişkiler için gerekli bir fazlalıktır. Kullanıcı veya grup listesi milyonları aştığında veya Gerçek Zamanlı Veritabanı güvenlik kuralları bazı kayıtlara erişimi engellediğinde bile, Ada'nın üyeliklerini hızlı ve verimli bir şekilde almanıza olanak tanır.
Kimlikleri anahtar olarak listeleyerek ve değeri true olarak ayarlayarak verileri tersine çeviren bu yaklaşım, bir anahtarın /users/$uid/groups/$group_id
okumak ve null
olup olmadığını kontrol etmek kadar basit hale getirir. Dizin, verileri sorgulamaktan veya taramaktan daha hızlı ve çok daha verimlidir.