Verileri Yapılandırma
Bu kılavuzda, veri mimarisindeki bazı temel kavramlar ve Firebase Realtime Database veritabanınızdaki JSON verilerini yapılandırmayla ilgili en iyi uygulamalar ele alınmaktadır.
Doğru şekilde yapılandırılmış bir veritabanı oluşturmak için önceden düşünmek gerekir. En önemlisi, verilerin nasıl kaydedileceğini ve daha sonra nasıl alınacağını planlamanız gerekir. Böylece bu süreci mümkün olduğunca kolaylaştırabilirsiniz.
Verilerin yapılandırılma şekli: JSON ağacıdır.
Tüm Firebase Realtime Database verileri JSON nesneleri olarak depolanır. Veritabanını bulutta barındırılan bir JSON ağacı olarak düşünebilirsiniz. SQL veritabanından farklı olarak
tablo veya kayıt yoktur. JSON ağacına veri eklediğinizde, bu veri mevcut JSON yapısında ilişkili bir anahtara sahip bir düğüm haline gelir. Kullanıcı kimlikleri veya semantik adlar gibi kendi anahtarlarınızı sağlayabilirsiniz. Alternatif olarak, Push() yöntemi kullanılarak anahtarlar sizin için sağlanabilir.
Örneğin, kullanıcıların temel bir profil ve kişi listesi depolamasına olanak tanıyan bir sohbet uygulaması düşünün. Tipik bir kullanıcı profili, /users/$uid gibi bir yolda bulunur. alovelace kullanıcısının veritabanı girişi şuna benzer 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 kodlar 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ıyla ilgili en iyi uygulamalar
Verileri iç içe yerleştirmekten kaçının
Firebase Realtime Database, 32 seviye derinliğe kadar iç içe yerleştirilmiş verilere izin verdiği için varsayılan yapının bu olması gerektiğini düşünebilirsiniz. Ancak veritabanınızdaki bir konumdan veri aldığınızda, bu konumun tüm alt düğümlerini de alırsınız. Ayrıca, veritabanınızdaki bir düğümde bir kullanıcıya okuma veya yazma erişimi verdiğinizde, bu kullanıcıya o düğümün altındaki tüm verilere erişim izni de vermiş olursunuz. Bu nedenle, pratikte veri yapınızı mümkün olduğunca düz tutmak en iyisidir.
İç içe yerleştirilmiş verilerin neden kötü olduğuna dair bir örnek için aşağıdaki çoklu iç içe yerleştirilmiş yapıyı inceleyin:
{ // 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 yerleştirilmiş tasarımda veriler üzerinde iterasyon yapmak sorunlu hale gelir. Örneğin, sohbet görüşmelerinin başlıklarını listelemek için tüm üyeler ve mesajlar dahil olmak üzere tüm chats ağacının istemciye indirilmesi gerekir.
Veri yapılarını düzleştirme
Veriler ayrı yollara bölünürse (normalleştirme kaldırma olarak da bilinir) gerektiğinde ayrı çağrılarla verimli bir şekilde indirilebilir. Şu düzleştirilmiş yapıyı inceleyin:
{ // 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 oda listesinde gezinebilir, odaları bir kullanıcı arayüzünde listelemek veya görüntülemek için meta verileri hızlıca getirebilirsiniz. Mesajlar ayrı ayrı alınabilir ve ulaştıkları anda gösterilebilir. Böylece kullanıcı arayüzü hızlı ve duyarlı kalır.
Ölçeklenebilir veriler oluşturma
Uygulama oluştururken genellikle bir listenin alt kümesini indirmek daha iyidir. Bu durum, özellikle listede binlerce kayıt varsa yaygındır. Bu ilişki statik ve tek yönlü olduğunda alt nesneleri üst nesnenin altına yerleştirebilirsiniz.
Bazen bu ilişki daha dinamiktir veya bu verilerin normalleştirilmesini kaldırmak gerekebilir. Çoğu zaman, Verileri Alma bölümünde açıklandığı gibi, verilerin bir alt kümesini almak için sorgu kullanarak verileri denormalize edebilirsiniz.
Ancak bu bile yeterli olmayabilir. Örneğin, kullanıcılar ve gruplar arasında iki yönlü bir ilişki olduğunu düşünelim. 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şır.
Kullanıcının ait olduğu grupları listelemenin ve yalnızca bu gruplara ait verileri getirmenin şık bir yolunu bulmak gerekir. Grupların dizini bu konuda ç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 } }, // ... } }
Bu işlemin, ilişkiyi hem Ada'nın kaydı hem de grup altında depolayarak bazı verileri kopyaladığını fark edebilirsiniz. Artık alovelace bir grup altında dizine eklenir ve techpioneers, Ada'nın profilinde listelenir. Bu nedenle, Ada'yı gruptan silmek için iki yerde güncelleme yapılması gerekir.
Bu, iki yönlü ilişkiler için gerekli bir fazlalıktır. Kullanıcı veya grup listesi milyonlara ulaştığında ya da Realtime Database güvenlik kuralları bazı kayıtlara erişimi engellediğinde bile Ada'nın üyeliklerini hızlı ve verimli bir şekilde getirmenize olanak tanır.
Kimlikleri anahtar olarak listeleyip değeri doğru olarak ayarlayarak verileri tersine çeviren bu yaklaşım, anahtar kontrolünü /users/$uid/groups/$group_id değerini okuyup null olup olmadığını kontrol etmek kadar basit hale getirir. Dizin, verileri sorgulamaktan veya taramaktan daha hızlı ve çok daha verimlidir.