Realm Adalah Solusi Database Android Terbaik
Diterbitkan: 2022-03-11Sejak Android dibuat, kami pengembang aplikasi telah menggunakan SQLite untuk menyimpan data lokal kami. Terkadang langsung dengan pernyataan SQL, terkadang menggunakan Object-Relational Mapper (ORM) sebagai lapisan abstraksi, tetapi bagaimanapun juga, kami telah menggunakan SQLite di penghujung hari.
Terlepas dari semua keunggulan SQLite, ada kalanya kami berharap kami memiliki alternatif untuk model relasional: Sesuatu yang dapat menghindarkan kami dari keharusan menambahkan kode boilerplate untuk mengonversi nilai ke dan dari database, atau memungkinkan kami untuk melewatkan pengaturan pemetaan antara kelas dan tabel, bidang dan kolom, kunci asing, dll.
Dengan kata lain, database dengan struktur data yang lebih mirip dengan yang sebenarnya kita gunakan di tingkat aplikasi. Lebih baik lagi, jika itu bisa hemat memori dengan desain, memungkinkan pengalaman yang lebih baik dalam perangkat yang dibatasi sumber daya, itu akan luar biasa.
Faktanya, ini adalah beberapa manfaat luar biasa yang kami dapatkan dengan Realm, platform database dengan arsitektur berbeda, yang telah muncul sebagai alternatif baru untuk SQLite.
Artikel ini menyajikan beberapa alasan utama mengapa Realm menarik begitu banyak perhatian dan mengapa Anda mungkin ingin mempertimbangkan untuk mencobanya. Ini membahas beberapa keuntungan utama yang diberikan Realm kepada pengembang Android dibandingkan SQLite.
Karena Realm tersedia di berbagai platform, beberapa dari apa yang akan dibahas dalam artikel ini memiliki relevansi dengan platform seluler lainnya, seperti iOS, Xamarin, dan React Native.
SQLite: Berhasil, tetapi Bukan Itu yang Sering Anda Butuhkan
Sebagian besar pengembang seluler mungkin akrab dengan SQLite. Sudah ada sejak tahun 2000, dan ini bisa dibilang mesin database relasional yang paling banyak digunakan di dunia.
SQLite memiliki sejumlah manfaat yang kita semua akui, salah satunya adalah dukungan aslinya di Android.
Fakta bahwa itu adalah database relasional SQL standar juga meminimalkan kurva belajar bagi mereka yang berasal dari latar belakang database relasional. Ini juga memberikan kinerja yang cukup baik jika digunakan secara maksimal (memanfaatkan fitur, seperti laporan yang disiapkan, operasi massal dengan transaksi, dll). Meskipun SQLite mungkin tidak berskala dengan baik untuk semua kebutuhan Anda.
Berurusan langsung dengan pernyataan SQL memiliki sejumlah kelemahan.
Menurut dokumentasi resmi Android, berikut adalah langkah-langkah yang diperlukan untuk mulai membaca/menulis ke SQLite:
- Jelaskan skema Anda dalam hal kelas kontrak.
- Tentukan perintah buat/jatuhkan tabel Anda dalam string.
- Perluas
SQLiteOpenHelper
untuk menjalankan perintah create dan mengelola upgrade/downgrade.
Setelah Anda selesai melakukannya, Anda akan siap untuk membaca dan menulis ke database Anda. Namun, Anda perlu mengonversi bolak-balik antara objek dalam aplikasi dan nilai dalam database. Singkat cerita: Ini banyak kode boilerplate!
Masalah lainnya adalah rawatan. Saat proyek Anda tumbuh lebih besar dan kebutuhan untuk menulis kueri yang lebih kompleks muncul, Anda akan berakhir dengan potongan besar kueri SQL mentah dalam string. Jika nanti Anda perlu mengubah logika kueri tersebut, itu bisa sangat merepotkan.
Terlepas dari kekurangannya, ada beberapa kasus di mana menggunakan SQL mentah adalah pilihan terbaik Anda. Salah satu contohnya adalah ketika Anda mengembangkan perpustakaan di mana kinerja dan ukuran merupakan faktor penting dan menambahkan perpustakaan pihak ketiga harus dihindari jika memungkinkan.
Object-Relational Mapper: Bantuan Band Untuk Tantangan SQL
Untuk menyelamatkan kita dari berurusan dengan SQL mentah, ORM datang untuk menyelamatkan.
Beberapa ORM Android yang paling terkenal adalah DBFlow, greenDAO, dan OrmLite.
Nilai terbesar yang mereka bawa adalah abstraksi SQLite, memungkinkan kita memetakan entitas database ke objek Java dengan relatif mudah.
Di antara manfaat lainnya, pengembang aplikasi dapat bekerja dengan objek, struktur data yang jauh lebih familiar. Ini juga membantu pemeliharaan, karena kami sekarang menangani objek tingkat tinggi dengan pengetikan yang lebih kuat dan meninggalkan pekerjaan kotor ke perpustakaan. Kurang berjuang dengan membangun kueri dengan menggabungkan string atau secara manual menangani koneksi dengan database. Lebih sedikit kesalahan ketik.
Meskipun fakta bahwa ORM ini telah meningkatkan standar database Android, mereka juga memiliki kekurangan. Dalam banyak kasus, Anda akhirnya memuat data yang tidak perlu.
Berikut adalah contoh.
Katakanlah Anda memiliki tabel dengan 15 kolom, dan di layar tertentu aplikasi Anda, daftar objek dari tabel ini ditampilkan. Daftar ini menampilkan nilai dari hanya tiga kolom. Oleh karena itu, dengan memuat semua data dari baris tabel, Anda akhirnya membawa data lima kali lebih banyak daripada yang sebenarnya Anda butuhkan untuk layar itu.
Sejujurnya, di beberapa perpustakaan ini Anda dapat menentukan kolom mana yang ingin Anda ambil di muka, tetapi untuk itu Anda perlu menambahkan kode lebih lanjut, dan meskipun demikian, itu tidak akan cukup jika Anda hanya dapat mengetahui dengan tepat kolom mana yang Anda inginkan. gunakan setelah Anda melihat data itu sendiri: beberapa data mungkin tidak perlu dimuat.
Selain itu, sering ada skenario di mana Anda harus membuat kueri kompleks, dan pustaka ORM Anda tidak menawarkan cara untuk mendeskripsikan kueri ini dengan API-nya. Itu bisa membuat Anda menulis kueri tidak efisien yang melakukan lebih banyak perhitungan daripada yang Anda butuhkan, misalnya.
Konsekuensinya adalah hilangnya kinerja, membuat Anda menggunakan SQL mentah. Meskipun ini bukan pemecah kesepakatan bagi banyak dari kita, itu melukai tujuan utama pemetaan relasional objek dan membawa kita kembali ke beberapa masalah yang disebutkan di atas mengenai SQLite.
Alam: Alternatif Sempurna
Realm Mobile Database adalah database yang dirancang untuk perangkat seluler dari awal.
Perbedaan utama antara Realm dan ORM adalah bahwa Realm bukanlah abstraksi yang dibangun di atas SQLite, tetapi mesin database yang sama sekali baru. Daripada model relasional, ini didasarkan pada penyimpanan objek. Intinya terdiri dari pustaka C++ mandiri. Saat ini mendukung Android, iOS (Objective-C dan Swift), Xamarin, dan React Native.
Realm diluncurkan pada Juni 2014, jadi saat ini berusia dua setengah tahun (cukup baru!).
Sementara teknologi database server mengalami revolusi sejak 2007, dengan banyak yang baru muncul, teknologi database untuk perangkat seluler tetap terjebak dengan SQLite dan pembungkusnya. Ini adalah salah satu motivasi utama untuk menciptakan sesuatu dari awal. Selanjutnya, seperti yang akan kita lihat, beberapa fitur Realm memerlukan perubahan mendasar pada cara database berperilaku pada tingkat rendah, dan itu tidak mungkin membangun sesuatu di atas SQLite.
Tetapi apakah Realm benar-benar layak? Berikut adalah alasan utama mengapa Anda harus mempertimbangkan untuk menambahkan Realm ke sabuk alat Anda.
Pemodelan yang mudah
Berikut ini contoh beberapa model yang dibuat dengan Realm:
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; }
Model Anda diperluas dari RealmObject. Realm menerima semua tipe primitif dan tipe kotaknya (kecuali untuk char
), String
, Date
dan byte[]
. Ini juga mendukung subkelas RealmObject
dan RealmList<? extends RealmObject>
RealmList<? extends RealmObject>
untuk memodelkan hubungan.
Bidang dapat memiliki tingkat akses apa pun (pribadi, publik, dilindungi, dll). Semua bidang dipertahankan secara default, dan Anda hanya perlu membubuhi keterangan bidang "khusus" (misalnya, @PrimaryKey
untuk bidang kunci utama Anda, @Ignore
untuk menyetel bidang yang tidak tetap, dll.).
Hal yang menarik tentang pendekatan ini adalah bahwa itu membuat kelas lebih sedikit "anotasi tercemar" dibandingkan dengan ORM, karena di sebagian besar dari mereka Anda memerlukan anotasi untuk memetakan kelas ke tabel, bidang reguler ke kolom database, bidang kunci asing ke tabel lain, dan sebagainya di.
Hubungan
Ketika datang ke hubungan, ada dua pilihan:
Tambahkan model sebagai bidang dari model lain. Dalam contoh kita, kelas
Contact
berisi bidangAddress
dan yang mendefinisikan hubungan mereka. Kontak mungkin memiliki alamat, tetapi tidak ada yang menghentikan alamat yang sama ini untuk ditambahkan ke kontak lain. Itu memungkinkan untuk satu-ke-satu dan satu-ke-banyak-hubungan.Tambahkan
RealmList
dari model yang direferensikan.RealmLists
berperilaku sepertiLists
Java lama yang baik, bertindak sebagai wadah objek Realm. Kita dapat melihat bahwa modelContact
kita memilikiRealmList
dari kontak, yang merupakan teman-temannya dalam contoh ini. Hubungan satu-ke-banyak dan banyak-ke-banyak dapat dimodelkan dengan pendekatan ini.
Saya suka cara merepresentasikan hubungan ini karena terasa sangat alami bagi kami pengembang Java. Dengan menambahkan objek ini (atau daftar objek ini) secara langsung sebagai bidang kelas kita, seperti yang akan kita lakukan untuk kelas non-model lainnya, kita tidak perlu berurusan dengan pengaturan SQLite untuk kunci asing.
Peringatan: Tidak ada dukungan untuk pewarisan model. Solusi saat ini adalah menggunakan komposisi. Jadi, jika, misalnya, Anda memiliki model Animal
dan berharap untuk membuat model Dog
yang diperluas dari Animal
, Anda harus menambahkan instance Animal
sebagai bidang di Dog
. Ada perdebatan besar tentang Komposisi vs Warisan. Jika Anda ingin menggunakan warisan, ini pasti sesuatu yang perlu Anda ketahui tentang Realm. Dengan SQLite, ini dapat diimplementasikan menggunakan dua tabel (satu untuk orang tua dan satu untuk anak) yang dihubungkan oleh kunci asing. Beberapa ORM juga tidak memberlakukan batasan ini, seperti DBFlow.
Ambil Hanya Data yang Anda Butuhkan! Desain nol-salinan
Ini adalah fitur pembunuh.
Realm menerapkan konsep desain zero-copy, yang berarti data tidak pernah disalin ke memori. Hasil yang Anda dapatkan dari kueri sebenarnya hanyalah petunjuk ke data sebenarnya. Data itu sendiri dimuat dengan malas saat Anda mengaksesnya.
Misalnya, Anda memiliki model dengan 10 bidang (kolom dalam SQL). Jika Anda meminta objek model ini untuk menampilkannya terdaftar di layar, dan Anda hanya perlu tiga dari 10 bidang untuk mengisi item daftar, itu akan menjadi satu-satunya bidang yang diambil.
Akibatnya, kueri menjadi sangat cepat (lihat di sini dan di sini untuk beberapa hasil benchmark).
Ini adalah keuntungan besar dibandingkan ORM yang biasanya memuat semua data dari baris SQL yang dipilih di muka.
Pemuatan layar menjadi jauh lebih efisien sebagai hasilnya tanpa memerlukan upaya lebih lanjut dari pengembang: itu hanya perilaku default Realm.
Selain itu, ini juga berarti bahwa aplikasi mengkonsumsi lebih sedikit memori dan, mengingat kita berbicara tentang lingkungan dengan sumber daya terbatas seperti perangkat seluler, yang dapat membuat perbedaan besar.
Konsekuensi lain dari pendekatan zero-copy adalah bahwa objek yang dikelola oleh Realm diperbarui secara otomatis.
Data tidak pernah disalin ke memori. Jika Anda memiliki hasil dari kueri, dan utas lain telah memperbarui data ini di database setelah kueri Anda, hasil yang Anda miliki akan mencerminkan perubahan ini. Hasil Anda hanyalah petunjuk ke data aktual. Jadi, saat Anda mengakses nilai dari bidang, data terbaru akan dikembalikan.
Jika Anda telah membaca data dari objek Realm dan menampilkannya di layar, misalnya, dan ingin menerima pembaruan saat data pokok berubah, Anda dapat menambahkan pendengar:
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 } });
Bukan Sekedar Pembungkus
Meskipun kami memiliki lusinan opsi untuk ORM, mereka adalah pembungkus, dan semuanya bermuara pada SQLite di bawahnya, yang membatasi seberapa jauh mereka bisa mendapatkannya. Sebaliknya, Realm bukan sekadar pembungkus SQLite. Ia memiliki kebebasan untuk menyediakan fitur yang tidak dapat ditawarkan oleh ORM.
Salah satu perubahan mendasar dengan Realm adalah dapat menyimpan data sebagai penyimpanan grafik objek.
Ini berarti Realm adalah objek sepenuhnya, dari level bahasa pemrograman hingga database. Akibatnya, ada lebih sedikit konversi yang dibuat bolak-balik saat Anda menulis dan membaca nilai, dibandingkan dengan database relasional.
Struktur database mencerminkan struktur data yang lebih dekat yang digunakan pengembang aplikasi. Faktanya, ini adalah salah satu alasan utama mengapa ada perpindahan dari pemodelan relasional dan menuju model agregat pada pengembangan sisi server. Realm akhirnya membawa beberapa ide ini ke dunia pengembangan seluler.
Jika kita memikirkan komponen dalam arsitektur Realm, di bagian bawah ada intinya dengan implementasi platform yang paling mendasar. Selain itu, kami akan memiliki perpustakaan yang mengikat ke setiap platform yang didukung.
Saat menggunakan pembungkus untuk beberapa teknologi yang tidak dapat Anda kendalikan, pada akhirnya Anda perlu menyediakan semacam lapisan abstraksi di sekitarnya.
Lib pengikatan alam dirancang setipis mungkin, untuk mengurangi kompleksitas abstraksi. Mereka kebanyakan menyebarkan ide desain dari Core. Dengan memiliki kendali atas seluruh arsitektur, komponen-komponen ini bekerja dalam sinkronisasi yang lebih baik satu sama lain.
Salah satu contoh praktis adalah akses ke objek referensi lainnya (kunci asing dalam SQL). Struktur file Realm didasarkan pada tautan asli, jadi ketika Anda menanyakan hubungan, daripada harus menerjemahkan abstraksi ORM ke relasional dan/atau menggabungkan beberapa tabel, Anda mendapatkan tautan mentah ke objek pada tingkat sistem file dalam format file.
Yaitu benda yang menunjuk langsung ke benda lain. Jadi, mengkueri suatu hubungan sama dengan mengkueri kolom bilangan bulat, misalnya. Tidak perlu operasi mahal melintasi kunci asing. Ini semua tentang mengikuti petunjuk.
Komunitas & Dukungan
Realm sedang dalam pengembangan aktif dan telah merilis versi yang diperbarui cukup sering.
Semua komponen dari Database Realm Mobile adalah open-source. Mereka sangat responsif pada pelacak masalah dan Stack Overflow, sehingga Anda dapat mengharapkan dukungan yang baik dan cepat di saluran ini.
Juga, umpan balik dari komunitas diperhitungkan saat memprioritaskan masalah (bug, peningkatan, permintaan fitur, dll.). Itu selalu baik untuk mengetahui Anda dapat memiliki suara dalam pengembangan alat yang Anda gunakan.
Saya mulai menggunakan Realm pada tahun 2015, dan sejak itu, saya menemukan beberapa posting di web dengan berbagai pendapat tentang Realm. Kami akan berbicara tentang batasannya segera, tetapi satu hal yang saya perhatikan adalah bahwa banyak keluhan yang dibuat pada saat posting telah diperbaiki.
Ketika saya mengetahui tentang Realm, misalnya, belum ada dukungan untuk metode khusus pada model dan panggilan asinkron. Ini adalah pemecah kesepakatan bagi banyak orang pada saat itu, tetapi keduanya saat ini didukung.
Kecepatan pengembangan dan responsivitas seperti itu membuat kami lebih yakin bahwa kami tidak akan menunggu lama untuk fitur-fitur penting.
Keterbatasan
Seperti segala sesuatu dalam hidup, Realm tidak semua mawar. Selain batasan warisan yang disebutkan sebelumnya, ada kekurangan lain yang perlu diingat:
Meskipun dimungkinkan untuk memiliki beberapa utas yang membaca dan menulis ke database secara bersamaan, objek Realm tidak dapat dipindahkan melintasi utas . Jadi, jika, misalnya, Anda mengambil objek ranah menggunakan
doInBackground()
AsyncTask, yang berjalan di utas latar belakang, Anda tidak dapat meneruskan instance ini ke metodeonPostExecute()
, karena itu berjalan di utas utama. Solusi yang mungkin untuk situasi ini adalah dengan membuat salinan objek dan meneruskannya atau meneruskan id objek dan mengambil objek lagi dionPostExecute()
. Realm menawarkan metode sinkron dan asinkron untuk membaca/menulis.Tidak ada dukungan untuk kunci utama peningkatan otomatis , jadi Anda harus menangani pembuatannya sendiri.
Tidak mungkin mengakses database dari proses yang berbeda secara bersamaan . Menurut dokumentasi mereka, dukungan multi-proses akan segera hadir.
Realm Adalah Masa Depan Solusi Basis Data Seluler
SQLite adalah mesin database yang solid, kuat, dan terbukti, dan database relasional tidak akan hilang dalam waktu dekat. Ada sejumlah ORM yang bagus di luar sana yang akan melakukan trik untuk banyak skenario juga.
Namun, penting untuk tetap up-to-date pada tren saat ini.
Dalam hal ini, saya pikir Realm adalah salah satu tren terbesar yang akan datang dalam beberapa tahun terakhir dalam hal pengembangan basis data seluler.
Realm membawa serta pendekatan unik untuk menangani data yang berharga bagi pengembang, tidak hanya karena itu bisa menjadi pilihan yang lebih baik daripada solusi yang ada, tetapi juga karena memperluas wawasan kita dalam hal kemungkinan baru dan meningkatkan standar teknologi basis data seluler.
Apakah Anda sudah memiliki pengalaman dengan Realm? Silakan berbagi pemikiran Anda.