Realm En İyi Android Veritabanı Çözümüdür
Yayınlanan: 2022-03-11Android oluşturulduğundan beri, biz uygulama geliştiricileri yerel verilerimizi depolamak için SQLite kullanıyoruz. Bazen doğrudan SQL ifadeleriyle, bazen soyutlama katmanı olarak Nesne-İlişkisel Eşleştirici (ORM) kullanarak, ancak her iki durumda da günün sonunda SQLite kullanıyoruz.
SQLite'ın tüm avantajlarına rağmen, ilişkisel bir modele alternatiflerimiz olmasını dilediğimiz zamanlar oldu: Bizi değerleri veritabanına ve veritabanından dönüştürmek için ortak kod eklemek zorunda kalmaktan kurtarabilecek veya eşlemeleri ayarlamayı atlamamızı sağlayabilecek bir şey sınıflar ve tablolar, alanlar ve sütunlar, yabancı anahtarlar vb. arasında
Başka bir deyişle, uygulama düzeyinde gerçekte kullandığımıza daha çok benzeyen veri yapılarına sahip bir veritabanı. Daha da iyisi, tasarımı gereği bellek açısından verimli olabilseydi ve kaynakları kısıtlı cihazlarda daha iyi deneyimlere izin verebilseydi, bu harika olurdu.
Aslında bunlar, SQLite'a yeni bir alternatif olarak ortaya çıkan, farklı bir mimariye sahip bir veritabanı platformu olan Realm ile elde ettiğimiz kullanıma hazır avantajlardan bazıları.
Bu makale, Realm'in neden bu kadar çok dikkat çekmesinin ana nedenlerinden bazılarını ve neden denemeyi düşünmek isteyebileceğinizi sunmaktadır. Realm'in Android geliştiricilerine SQLite üzerinden sağladığı bazı önemli avantajları tartışıyor.
Realm birden fazla platformda mevcut olduğundan, bu makalede ele alınacak olanlardan bazıları iOS, Xamarin ve React Native gibi diğer mobil platformlarla da ilgilidir.
SQLite: Çalışıyor, Ama Çoğu Zaman İhtiyacınız Olan Bu Değil
Çoğu mobil geliştirici muhtemelen SQLite'a aşinadır. 2000'den beri var ve tartışmasız dünyanın en çok kullanılan ilişkisel veritabanı motorudur.
SQLite, Android'deki yerel desteği olan, hepimizin kabul ettiği bir dizi avantaja sahiptir.
Standart bir SQL ilişkisel veritabanı olması da ilişkisel veritabanı altyapısından gelenler için öğrenme eğrisini en aza indirir. Ayrıca, tam potansiyeliyle kullanıldığında (hazırlanmış ifadeler, işlemlerle toplu işlemler, vb. gibi özelliklerden yararlanma) oldukça iyi bir performans sağlar. SQLite, tüm ihtiyaçlarınız için çok iyi ölçeklenmeyebilir.
Yine de, doğrudan SQL ifadeleriyle uğraşmanın bir takım olumsuz yönleri vardır.
Resmi Android belgelerine göre, SQLite'a okumaya/yazmaya başlamak için gereken adımlar şunlardır:
- Şemanızı sözleşme sınıfları açısından tanımlayın.
- Tablo oluşturma/bırakma komutlarınızı dizelerde tanımlayın.
-
SQLiteOpenHelper
, oluşturma komutlarını çalıştırmak ve yükseltmeleri/düşürmeleri yönetmek için genişletin.
Bunu yaptıktan sonra, veritabanınıza okumaya ve yazmaya hazır olacaksınız. Ancak, uygulamanızdaki nesneler ile veritabanındaki değerler arasında ileri geri dönüştürmeniz gerekecektir. Uzun lafın kısası: Çok fazla ortak kod var!
Bir diğer konu da sürdürülebilirlik. Projeniz büyüdükçe ve daha karmaşık sorgular yazma ihtiyacı ortaya çıktıkça, dizelerde büyük miktarda ham SQL sorgusu elde edeceksiniz. Daha sonra bu sorguların mantığını değiştirmeniz gerekirse, bu oldukça zor olabilir.
Olumsuz yönlerine rağmen, ham SQL kullanmanın en iyi seçenek olduğu durumlar vardır. Bir örnek, performansın ve boyutun kritik faktörler olduğu ve mümkünse üçüncü taraf kitaplık eklemekten kaçınılması gereken bir kitaplık geliştirirken verilebilir.
Nesne-İlişkisel Eşleştirici: SQL Zorlukları için Yara bandı
Bizi ham SQL ile uğraşmaktan kurtarmak için ORM'ler kurtarmaya geldi.
En ünlü Android ORM'lerinden bazıları DBFlow, greenDAO ve OrmLite'dir.
Getirdikleri en büyük değer, veritabanı varlıklarını nispeten kolay Java nesnelerine eşlememize izin veren SQLite soyutlamasıdır.
Diğer faydaların yanı sıra, uygulama geliştiriciler, çok daha tanıdık bir veri yapısı olan nesnelerle çalışabilirler. Ayrıca, üst düzey nesneleri artık daha güçlü bir yazımla ele aldığımız ve kirli işleri kitaplıklara bıraktığımız için, sürdürülebilirliğe de yardımcı oluyor. Dizeleri birleştirerek veya veritabanıyla bağlantıyı manuel olarak yöneterek sorgu oluşturmakla daha az uğraşır. Daha az yazım hatası.
Bu ORM'lerin Android veritabanlarında çıtayı yükselttiği bir gerçek olsa da, dezavantajları da var. Çoğu durumda, gereksiz verileri yüklersiniz.
İşte bir örnek.
Diyelim ki 15 sütunlu bir tablonuz var ve uygulamanızın belirli bir ekranında bu tablodaki nesnelerin bir listesi görüntüleniyor. Bu liste, yalnızca üç sütundaki değerleri görüntüler. Bu nedenle, tablo satırındaki tüm verileri yükleyerek, o ekran için gerçekten ihtiyaç duyduğunuzdan beş kat daha fazla veri getirmiş olursunuz.
Gerçeği söylemek gerekirse, bu kitaplıkların bazılarında, hangi sütunları önceden almak istediğinizi belirtebilirsiniz, ancak bunun için daha fazla kod eklemeniz gerekir ve buna rağmen, yalnızca tam olarak hangi sütunları alacağınızı bilmeniz durumunda bu yeterli olmayacaktır. verilerin kendisine baktıktan sonra kullanın: yine de bazı veriler gereksiz yere yüklenmiş olabilir.
Ek olarak, genellikle yapmak için karmaşık sorgularınız olduğu senaryolar vardır ve ORM kitaplığınız size bu sorguları API'si ile açıklamanın bir yolunu sunmaz. Bu, örneğin ihtiyacınız olandan daha fazla hesaplama yapan verimsiz sorgular yazmanıza neden olabilir.
Sonuç, ham SQL'e başvurmanıza yol açan bir performans kaybıdır. Bu, çoğumuz için bir anlaşma kırıcı olmasa da, nesne-ilişkisel eşlemenin asıl amacına zarar veriyor ve bizi SQLite ile ilgili yukarıda bahsedilen bazı konulara geri götürüyor.
Diyar: Mükemmel Bir Alternatif
Realm Mobile Database, sıfırdan mobil cihazlar için tasarlanmış bir veritabanıdır.
Realm ve ORM'ler arasındaki temel fark, Realm'in SQLite üzerine inşa edilmiş bir soyutlama değil, tamamen yeni bir veritabanı motoru olmasıdır. İlişkisel bir modelden ziyade bir nesne deposuna dayanır. Çekirdeği, bağımsız bir C++ kitaplığından oluşur. Şu anda Android, iOS(Objective-C ve Swift), Xamarin ve React Native'i desteklemektedir.
Realm Haziran 2014'te piyasaya sürüldü, bu nedenle şu anda iki buçuk yaşında (oldukça yeni!).
Sunucu veritabanı teknolojileri 2007'den bu yana birçok yenisinin ortaya çıkmasıyla bir devrim yaşarken, mobil cihazlar için veritabanı teknolojisi SQLite ve paketleyicilerine takılıp kaldı. Bu, sıfırdan bir şey yaratmanın temel motivasyonlarından biriydi. Ayrıca, göreceğimiz gibi, Realm'in bazı özellikleri, bir veritabanının düşük düzeyde davranış biçiminde temel değişiklikler gerektiriyordu ve bu, SQLite üzerine bir şey inşa etmek mümkün değildi.
Ama Realm gerçekten buna değer mi? Alet kemerinize Diyar'ı eklemeyi düşünmeniz için en önemli nedenler burada.
Kolay modelleme
Realm ile oluşturulmuş bazı modellere bir örnek:
public class Contact extends RealmObject { @PrimaryKey String id; protected String name; String email; @Ignore public int sessionId; //Relationships private Address address; private RealmList<Contact> friends; //getters & setter left out for brevity }
public class Address extends RealmObject { @PrimaryKey public Long id; public String name; public String address; public String city; public String state; public long phone; }
Modelleriniz RealmObject'den uzanır. Bölge, tüm ilkel türleri ve kutulu türlerini ( char
hariç), String
, Date
ve byte[]
kabul eder. Ayrıca RealmObject
ve RealmList<? extends RealmObject>
alt sınıflarını da destekler. RealmList<? extends RealmObject>
ilişkileri modellemek için genişletir.
Alanlar herhangi bir erişim düzeyine sahip olabilir (özel, genel, korumalı vb.). Tüm alanlar varsayılan olarak kalıcıdır ve "özel" alanlara açıklama eklemeniz yeterlidir (örneğin, birincil anahtar alanınız için @PrimaryKey
, kalıcı olmayan alanları ayarlamak için @Ignore
, vb.).
Bu yaklaşımla ilgili ilginç olan şey, ORM'lere kıyasla sınıfları daha az "açıklama kirli" tutmasıdır, çünkü bunların çoğunda sınıfları tablolara, normal alanları veritabanı sütunlarına, yabancı anahtar alanlarını diğer tablolara eşlemek için ek açıklamalara ihtiyaç duyarsınız. üzerinde.
ilişkiler
İlişkiler söz konusu olduğunda, iki seçenek vardır:
Başka bir modelden alan olarak bir model ekleyin. Örneğimizde,
Contact
sınıfı, ilişkilerini tanımlayan birAddress
alanı içerir. Bir kişinin bir adresi olabilir, ancak hiçbir şey aynı adresin diğer kişilere eklenmesini engellemez. Bu, bire bir ve bire çok ilişkilere izin verir.Başvurulan modellerin bir
RealmList
ekleyin.RealmLists
, Realm nesnelerinin bir kapsayıcı görevi görerek eski JavaLists
gibi davranır.Contact
modelimizin bu örnekte arkadaşları olan birRealmList
kişi listesine sahip olduğunu görebiliriz. Bire çoğa ve çoktan çoğa ilişkiler bu yaklaşımla modellenebilir.
İlişkileri bu şekilde temsil etmeyi seviyorum çünkü biz Java geliştiricileri için çok doğal geliyor. Bu nesneleri (veya bu nesnelerin listelerini) doğrudan sınıfımızın alanları olarak ekleyerek, tıpkı diğer model olmayan sınıflar için yaptığımız gibi, yabancı anahtarlar için SQLite ayarlarıyla uğraşmamıza gerek kalmaz.
Uyarı: Model devralma desteği yoktur. Geçerli geçici çözüm, kompozisyon kullanmaktır. Bu nedenle, örneğin, bir Animal
modeliniz varsa ve Animal
'dan uzanan bir Dog
modeli oluşturmayı umuyorsanız, bunun yerine Animal
örneğini Dog
içine alan olarak eklemeniz gerekir. Kompozisyon ve Kalıtım hakkında büyük bir tartışma var. Kalıtımı kullanacaksanız, bu kesinlikle Realm hakkında bilmeniz gereken bir şeydir. SQLite ile bu, bir yabancı anahtarla birbirine bağlanan iki tablo (biri ebeveyn için diğeri çocuk için) kullanılarak uygulanabilir. DBFlow gibi bazı ORM'ler de bu kısıtlamayı uygulamaz.
Yalnızca İhtiyacınız Olan Verileri Alın! Sıfır Kopya Tasarımı
Bu öldürücü bir özellik.
Realm, sıfır kopya tasarımı kavramını uygular; bu, verilerin asla belleğe kopyalanmadığı anlamına gelir. Bir sorgudan elde ettiğiniz sonuçlar aslında sadece gerçek verilere işaret eder. Verilerin kendisi, siz ona erişirken tembelce yüklenir.
Örneğin, 10 alanlı bir modeliniz var (SQL'de sütunlar). Bu modelin nesnelerini bir ekranda listelenmiş olarak görüntülemek için sorgularsanız ve liste öğelerini doldurmak için 10 alandan sadece üçüne ihtiyacınız varsa, bunlar yalnızca alınan alanlar olacaktır.
Sonuç olarak, sorgular inanılmaz derecede hızlıdır (bazı kıyaslama sonuçları için buraya ve buraya bakın).
Bu, genellikle tüm verileri seçili SQL satırlarından önceden yükleyen ORM'lere göre büyük bir avantajdır.
Sonuç olarak, geliştiricinin daha fazla çaba göstermesine gerek kalmadan ekran yükleme çok daha verimli hale gelir: bu yalnızca Realm'in varsayılan davranışıdır.
Ek olarak, bu aynı zamanda uygulamaların daha az bellek tükettiği ve mobil cihazlar gibi kaynak kısıtlı bir ortamdan bahsettiğimizi düşünürsek, bunun büyük bir fark yaratabileceği anlamına gelir.
Sıfır kopya yaklaşımının bir başka sonucu da, Realm tarafından yönetilen nesnelerin otomatik olarak güncellenmesidir.
Veriler asla belleğe kopyalanmaz. Bir sorgudan sonuçlarınız varsa ve sorgunuzdan sonra başka bir iş parçacığı bu verileri veritabanında güncellediyse, sahip olduğunuz sonuçlar bu değişiklikleri zaten yansıtacaktır. Sonuçlarınız yalnızca gerçek verilere işaret eder. Böylece alanlardan değerlere eriştiğinizde en güncel veriler döndürülür.
Örneğin, Realm nesnelerinden verileri zaten okuduysanız ve bunları ekranda görüntülediyseniz ve temel alınan veriler değiştiğinde güncellemeler almak istiyorsanız, bir dinleyici ekleyebilirsiniz:
final RealmResults<Contact> johns = realm.where(Contact.class).beginsWith("name", "John ").findAll(); johns.addChangeListener(new RealmChangeListener<RealmResults<Contact>>() { @Override public void onChange(RealmResults<Contact> results) { // UPDATE UI } });
Bu Sadece Bir Sarıcı Değil
ORM'ler için düzinelerce seçeneğimiz olmasına rağmen, bunlar sarmalayıcıdır ve her şey altta SQLite'a bağlıdır, bu da ne kadar ileri gidebileceklerini sınırlar. Buna karşılık, Bölge yalnızca başka bir SQLite sarmalayıcı değildir. ORM'lerin sunamadığı özellikleri sağlama özgürlüğüne sahiptir.
Realm'deki temel değişikliklerden biri, verileri bir nesne grafiği deposu olarak depolayabilmektir.
Bu, Realm'in programlama dili seviyesinden veritabanına kadar tamamen nesneler olduğu anlamına gelir. Sonuç olarak, ilişkisel bir veritabanına kıyasla, siz değerleri yazarken ve okurken ileri geri yapılan dönüşüm çok daha azdır.
Veritabanı yapıları, uygulama geliştiricilerin kullandığı veri yapılarını daha yakından yansıtır. Aslında bu, ilişkisel modellemeden sunucu tarafı geliştirmede toplu modellere doğru bir hareket olmasının ana nedenlerinden biridir. Realm sonunda bu fikirlerden bazılarını mobil geliştirme dünyasına getiriyor.
Realm mimarisindeki bileşenleri düşünürsek, en altta platformun en temel uygulamasına sahip çekirdeği vardır. Bunun üzerine, desteklenen her platforma bağlayıcı kitaplıklarımız olacak.
Üzerinde hiçbir kontrolünüz olmayan bir teknoloji için bir sarmalayıcı kullanırken, sonunda onun etrafında bir çeşit soyutlama katmanı sağlamanız gerekir.
Bölge bağlama kitaplıkları, soyutlama karmaşıklığını ortadan kaldırmak için mümkün olduğunca ince olacak şekilde tasarlanmıştır. Tasarım fikrini çoğunlukla Core'dan yayıyorlar. Tüm mimarinin kontrolüne sahip olarak, bu bileşenler birbirleriyle daha iyi senkronize çalışır.
Pratik bir örnek, başvurulan diğer nesnelere erişimdir (SQL'deki yabancı anahtarlar). Realm'in dosya yapısı yerel bağlantılara dayalıdır, bu nedenle ilişkileri sorguladığınızda, bir ORM soyutlamasını ilişkisel olarak çevirmek ve/veya birden çok tabloya katılmak yerine, dosya biçiminde bir dosya sistemi düzeyinde nesnelere ham bağlantılar alırsınız.
Bu, doğrudan diğer nesnelere işaret eden nesnelerdir. Bu nedenle, örneğin bir ilişkiyi sorgulamak, bir tamsayı sütununu sorgulamakla aynıdır. Yabancı anahtarlar arasında geçiş yapan pahalı işlemlere gerek yok. Her şey işaretçileri takip etmekle ilgili.
Topluluk ve Destek
Realm aktif geliştirme aşamasındadır ve güncellenmiş sürümleri oldukça sık yayınlamaktadır.
Realm Mobile Database'deki tüm bileşenler açık kaynaklıdır. Sorun izleyici ve Yığın Taşması konusunda çok duyarlılar, bu nedenle bu kanallarda iyi ve hızlı destek bekleyebilirsiniz.
Ayrıca, sorunlara (hatalar, iyileştirmeler, özellik istekleri vb.) öncelik verilirken topluluktan gelen geri bildirimler dikkate alınır. Kullandığınız araçların geliştirilmesinde söz sahibi olabileceğinizi bilmek her zaman iyidir.
Realm'i 2015'te kullanmaya başladım ve o zamandan beri web'de Realm hakkında çeşitli görüşler içeren birkaç gönderiyle karşılaştım. Sınırlamaları hakkında yakında konuşacağız, ancak fark ettiğim bir şey, gönderi sırasında yapılan şikayetlerin çoğunun o zamandan beri düzeltilmiş olması.
Örneğin Realm'i öğrendiğimde, modellerde ve asenkron çağrılarda özel yöntemler için henüz destek yoktu. Bunlar, o zamanlar birçokları için anlaşma kırıcıydı, ancak şu anda her ikisi de destekleniyor.
Bu geliştirme hızı ve yanıt hızı, önemli özellikler için uzun süre beklemeyeceğimizden emin olmamızı sağlıyor.
sınırlamalar
Hayattaki her şeyde olduğu gibi, Diyar da güllerden ibaret değildir. Daha önce bahsedilen miras sınırlamasının yanı sıra, akılda tutulması gereken başka eksiklikler de vardır:
Aynı anda veritabanından okuma ve veritabanına yazma birden çok iş parçacığına sahip olmak mümkün olsa da, Realm nesneleri iş parçacıkları arasında taşınamaz . Dolayısıyla, örneğin, bir arka plan iş parçacığında çalışan
doInBackground()
kullanarak bir bölge nesnesi alırsanız, bu örneğionPostExecute()
yöntemlerine iletemezsiniz, çünkü bunlar ana iş parçacığında çalışır. Bu durum için olası geçici çözümler, nesnenin bir kopyasını oluşturmak ve iletmek veya nesnenin kimliğini iletmek ve nesneyionPostExecute()
üzerinde yeniden almak olabilir. Realm, okuma/yazma için senkron ve asenkron yöntemler sunar.Otomatik artışlı birincil anahtarlar için destek yoktur , bu nedenle bunların oluşturulmasını kendiniz halletmeniz gerekir.
Veritabanına aynı anda farklı işlemlerden erişmek mümkün değildir . Belgelerine göre, çok işlemli destek yakında geliyor.
Realm, Mobil Veritabanı Çözümlerinin Geleceğidir
SQLite sağlam, sağlam ve kanıtlanmış bir veritabanı motorudur ve ilişkisel veritabanları yakın zamanda ortadan kalkmayacaktır. Pek çok senaryo için de işe yarayacak çok sayıda iyi ORM var.
Ancak, güncel trendleri takip etmek önemlidir.
Bu bağlamda, mobil veritabanı geliştirme söz konusu olduğunda, Realm'in son yıllarda gelecek en büyük trendlerden biri olduğunu düşünüyorum.
Realm, yalnızca mevcut çözümlerden daha iyi bir seçenek olabileceği için değil, aynı zamanda yeni olanaklar açısından ufkumuzu genişlettiği ve mobil veritabanı teknolojisinde çıtayı yükselttiği için geliştiriciler için değerli olan verilerle başa çıkmak için benzersiz bir yaklaşım getiriyor.
Realm ile zaten deneyiminiz var mı? Lütfen düşüncelerinizi paylaşmaktan çekinmeyin.