Realm یک پایگاه داده NoSQL شیءگرای موبایل است که به عنوان جایگزینی برای SQLite و Core Data در iOS و Android طراحی شده است. دادهها در قالب اختصاصی با دسترسی مستقیم به اشیاء در حافظه ذخیره میشوند که سرعت بالای خواندن و نوشتن را تضمین میکند. به لطف اعلانهای واکنشگرا، همگامسازی خودکار از طریق Realm Sync و مدل دادههای بینپلتفرمی، Realm در بیش از ۱ میلیارد دستگاه استفاده میشود (دادههای MongoDB، ۲۰۲۵).
نکات کلیدی
Realm یک پایگاه داده شیءگرا است که به طور خاص برای اپلیکیشنهای موبایل ساخته شده است. بر خلاف SQLite، Realm از SQL و مدل رابطهای استفاده نمیکند — دادهها به عنوان اشیاء زنده (Live Objects) ذخیره میشوند که دسترسی به آنها مستقیماً و بدون لایه میانی ORM انجام میشود. توسعهدهنده با اشیاء معمولی زبان (Swift، Kotlin، Dart) کار میکند که به طور خودکار در پایگاه داده ذخیره میشوند.
Realm در سال ۲۰۱۴ به عنوان یک استارتاپ به نام Realm Inc. ظهور کرد و در سال ۲۰۱۹ توسط MongoDB Inc. خریداری شد. از آن زمان، Realm به عنوان MongoDB Realm — بخشی از پلتفرم یکپارچه Atlas Device Sync برای همگامسازی دادههای موبایل — توسعه مییابد. پایگاه داده محلی Realm رایگان و متنباز باقی میماند (مجوز Apache 2.0) و Realm Sync (همگامسازی ابری) به صورت اشتراکی ارائه میشود.
بر اساس گزارش MongoDB Developer Report (۲۰۲۵)، Realm در ۱۵٪ از اپلیکیشنهای موبایل به عنوان ذخیرهساز محلی اصلی استفاده میشود. سناریوهای اصلی شامل برنامههای دارای حالت آفلاین، مدلهای شیء پیچیده و نیاز به همگامسازی بین دستگاهها است، جایی که Realm از SQLite از نظر سرعت توسعه و سهولت کار با اشیاء پیشی میگیرد.
Live Objects — هر شیء Realm از طریق نگاشت حافظه (memory-mapped file) به دیسک متصل است. تغییر شیء در هر رشتهای بلافاصله در تمام رشتههای دیگر بدون اطلاعرسانی دستی منعکس میشود. رابط کاربری با تغییر دادهها از طریق اعلانهای Realm به طور خودکار بازترسیم میشود. Zero-copy — Realm دادهها را از پایگاه داده به اشیاء کپی نمیکند، اشیاء خود دادهها در حافظه هستند.
هسته Realm به زبان C++ نوشته شده و از B+ Tree برای نمایهسازی دادهها استفاده میکند. بر خلاف SQLite که هر ردیف یک رکورد در جدول رابطهای است، Realm اشیاء را به عنوان گرههایی در ساختار گرافی با ارجاعات مستقیم بین آنها (forward pointers) ذخیره میکند. روابط بین اشیاء کلیدهای خارجی نیستند، بلکه اشارهگرهای مستقیم هستند که نیاز به عملیات JOIN را از بین میبرد.
فایلهای Realm (با پسوند .realm) memory-mapped هستند — سیستم عامل خود بارگذاری صفحات فایل را در حافظه با دسترسی مدیریت میکند. این به Realm اجازه میدهد با پایگاههای دادهای بزرگتر از حافظه رم موجود کار کند و تأخیر خواندن را در سطح ساختارهای داده بومی زبان (Swift Array یا Kotlin List) برای دادههای قابل جایگیری در RAM تضمین میکند.
فایلهای Memory-mapped — فناوری کلیدی Realm. به جای کپی کردن دادهها از فایل پایگاه داده به اشیاء زبان (همانطور که SQLite از طریق sqlite3_step + sqlite3_column_* انجام میدهد)، Realm فایل پایگاه را مستقیماً به فضای آدرس فرآیند نگاشت میکند. اشیاء زبان صرفاً اشارهگرهایی به دادهها در حافظه نگاشتشده هستند. تغییر یک شیء پایگاه داده را روی دیسک بدون فراخوانی جداگانه save تغییر میدهد.
| ویژگی | Realm (zero-copy) | SQLite (کپی) |
|---|---|---|
| خواندن | دسترسی مستقیم به حافظه (نانوثانیه) | کپی در شیء (میکروثانیه) |
| نوشتن | نوشتن فوری در memory-mapped file | save() با تراکنش SQL INSERT/UPDATE |
| روابط | اشارهگرهای مستقیم (forward pointers) | کلید خارجی + JOIN |
| مصرف حافظه | فایل + کش صفحه سیستم عامل | اشیاء + کش صفحه SQLite |
| اشیاء زنده | بله (بهروزرسانی خودکار) | خیر (نیاز به واکشی مجدد) |
مصرف حافظه Realm در خواندن فعال بیشتر است (کل فایل یا بخش بزرگی از آن در حافظه نگاشت میشود)، اما در عملیات نوشتن کمتر است، زیرا نیازی به تخصیص حافظه برای کپی اشیاء نیست. برای پایگاههای داده تا ۱ گیگابایت در دستگاههای موبایل، رویکرد memory-mapped عملکرد کلی بهتری نسبت به SQLite با کپی میانی آن ارائه میدهد.
SQLite یک سیستم مدیریت پایگاه داده رابطهای با SQL و تراکنشهای ACID است. Realm یک پایگاه داده NoSQL شیءگرا با دسترسی memory-mapped است. Core Data یک لایه ORM اپل بر روی SQLite است. هر یک از سه رویکرد حوزه کاربرد و نقاط قوت خود را دارد. Realm در سرعت دسترسی مستقیم به اشیاء و واکنشگرایی برنده است، SQLite در جهانیبودن و بلوغ، و Core Data در یکپارچگی با اکوسیستم اپل.
عملکرد Realm در عملیات خواندن ۱۰-۵۰٪ بالاتر از SQLite به دلیل دسترسی zero-copy است. در عملیات نوشتن نیز Realm به دلیل عدم وجود تجزیه نحوی SQL و تغییر مستقیم صفحات memory-mapped سریعتر است. با این حال، Realm ممکن است حافظه رم بیشتری را هنگام کار با پایگاههای داده بزرگ (>۵۰۰ مگابایت) مصرف کند، زیرا فایل به طور کامل در فضای آدرس نگاشت میشود.
| معیار | Realm | SQLite | Core Data |
|---|---|---|---|
| نوع | پایگاه داده NoSQL شیءگرا | سیستم مدیریت پایگاه داده رابطهای (SQL) | ORM بر روی SQLite |
| سرعت خواندن | بالا (zero-copy) | متوسط | متوسط (سربار ORM) |
| واکنشگرایی | Live Objects (داخلی) | نیاز به wrapper (Room/GRDB) | NSFetchedResultsController |
| همگامسازی | Realm Sync (MongoDB Atlas) | نیاز به پیادهسازی سفارشی | NSPersistentCloudKitContainer |
| پلتفرمها | iOS, Android, Flutter, RN, Node.js | iOS, Android, Web, Desktop | فقط iOS/macOS |
| اندازه کتابخانه | ~۴ مگابایت | ~۶۰۰ کیلوبایت | تعبیهشده در SDK |
انتخاب بین Realm و SQLite اغلب به اولویتها بستگی دارد: سرعت توسعه و واکنشگرایی (Realm) در مقابل کنترل و جهانیبودن (SQLite). Realm به ویژه برای MVP و نمونههای اولیه مناسب است، جایی که مدل داده اغلب تغییر میکند و دریافت بهروزرسانیهای زنده برای UI مهم است. SQLite/Room برای محصولات بالغ با حجم داده زیاد و کوئریهای تحلیلی پیچیده ترجیح داده میشود.
Realm Kotlin SDK کتابخانه رسمی برای Android است که به زبان Kotlin نوشته شده است (نه یک wrapper بر روی Java SDK). مدل داده از طریق کلاسهایی که از RealmObject ارثبری میکنند با حاشیهنویسی @PrimaryKey برای شناسه منحصربهفرد تعریف میشود. Realm Kotlin از Kotlin Coroutines، Flow و KSP (Kotlin Symbol Processing) برای تولید کد در زمان کامپایل پشتیبانی میکند.
RealmQuery یک API type-safe برای فیلتر کردن بدون SQL ارائه میدهد. کوئریها با زنجیرهای از متدها ساخته میشوند: query → filter → sort → find. نتیجه میتواند به صورت لیست (با بارگذاری در حافظه) یا به صورت Flow (جریان واکنشگرا که با تغییر دادهها بهروز میشود) بازگردانده شود. Realm Kotlin همچنین از اشیاء تو در تو و لیستها (RealmList) پشتیبانی میکند.
مدل داده Realm به عنوان data class که رابط RealmObject را پیادهسازی میکند تعریف میشود. فیلد _id با @PrimaryKey برای شناسایی منحصربهفرد مشخص شده است. رابطه «یک-به-چند» از طریق RealmList — لیستی از سایر RealmObjectها — پیادهسازی میشود. تمام عملیات نوشتن (create، update، delete) در داخل بلوک تراکنش write انجام میشوند.
class Project : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var name: String = ""
var tasks: RealmList<Task> = realmListOf()
}
class Task : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var title: String = ""
var isComplete: Boolean = false
}
val config = Realm.Configuration.Builder(
schema = setOf(Project::class, Task::class)
).build()
val realm = Realm.open(config)
realm.write { transactionRealm ->
val project = copyToRealm(Project().apply {
name = "Mobile App"
})
project.tasks.add(copyToRealm(Task().apply {
title = "Design UI"
}))
}
val projects: Flow<RealmResults<Project>> =
realm.query<Project>()
.sort(Project::name, Sort.ASCENDING)
.asFlow()
کوئری برگشتی Flow به طور خودکار نتایج جدید را با هر تغییر داده در Realm منتشر میکند: افزودن، بهروزرسانی یا حذف Project یا Task. رویکرد Flow به طور ایدهآل با Compose ترکیب میشود: collectAsState() در ViewModel به طور خودکار UI را با تغییر دادهها بدون بهروزرسانی دستی آداپتورهای لیست یا استفاده از LiveData بازترکیب میکند.
Realm Swift SDK یک API بومی Swift با پشتیبانی از async/await، Combine Publishers و Swift Concurrency ارائه میدهد. مدلهای داده به صورت کلاسهایی که از Object ارثبری میکنند با استفاده از @Persisted برای ویژگیها تعریف میشوند. Realm Swift به طور خودکار اشیاء را با تغییرات بهروز میکند و اعلانها (NotificationToken) امکان اشتراک در تغییرات اشیاء یا مجموعههای جداگانه را فراهم میکنند.
@ObservedRealmObject و @ObservedResults — Property Wrapperهایی برای SwiftUI هستند که به طور خودکار View را با تغییر دادههای Realm بازترسیم میکنند. @ObservedResults با نتایج کوئری کار میکند، @ObservedRealmObject با یک شیء خاص. هر دو ویژگی اشتراک را هنگام حذف نهایی View لغو میکنند.
یکپارچگی SwiftUI Realm یکی از نقاط قوت SDK است. Property Wrapper @ObservedResults یک کوئری Realm را با نمایش در SwiftUI پیوند میدهد. با تغییر هر وظیفه، SwiftUI به طور خودکار لیست را بازترکیب میکند. realm.writeAsync تراکنشها را در رشته پسزمینه بدون مسدود کردن UI انجام میدهد.
import RealmSwift
class TaskItem: Object, Identifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var title: String = ""
@Persisted var isDone: Bool = false
@Persisted var priority: Int = 0
}
struct TaskListView: View {
@ObservedResults(TaskItem.self,
sortDescriptor: SortDescriptor(["priority"]))
var tasks
var body: some View {
List {
ForEach(tasks) { task in
TaskRow(task: task)
}
}
Button("افزودن وظیفه") {
let realm = try! Realm()
try! realm.write {
realm.add(TaskItem(value: ["title": "New task"]))
}
}
}
}
@ObservedResults به طور خودکار چرخه عمر کوئری Realm را مدیریت میکند: هنگام ایجاد View، اشتراکی برای تغییرات ایجاد میشود و هنگام حذف، لغو میشود. Property Wrapper یک predicate اختیاری (NSPredicate) و مرتبسازی میپذیرد. این کار نیاز به نوشتن دستی کوئریهای fetch، ایجاد ViewModel و اشتراک در اعلانهای Realm را از بین میبرد.
برنامههای آفلاین — Realm برای سناریوهایی که دادهها باید بدون اینترنت در دسترس باشند ایدهآل است. همگامسازی داخلی (Realm Sync با MongoDB Atlas) به طور خودکار تعارضات را هنگام اتصال به شبکه حل میکند. برنامه با دادههای محلی به کار خود ادامه میدهد و همگامسازی پسزمینه هنگام برقراری اتصال آنها را بهروز میکند.
رابطهای کاربری واکنشگرا — Live Objects و اعلانهای Flow/Combine Realm را به انتخابی مناسب برای برنامههایی با دادههای مکرراً بهروزشونده تبدیل میکند: چتها، فیدهای وظایف، اسناد مشترک. UI با افزودن، تغییر یا حذف دادهها بدون فراخوانی دستی reloadData یا invalidate به طور خودکار بهروز میشود.
پروژههای بینپلتفرمی — Realm از Kotlin Multiplatform (KMP)، Flutter، React Native و Xamarin پشتیبانی میکند. مدل داده یک بار تعریف شده و در تمام پلتفرمها استفاده میشود. این کار تکرار کد را کاهش میدهد و سازگاری طرح داده را بین برنامههای iOS و Android با منطق تجاری مشترک تضمین میکند.
Realm Sync یک سرویس ابری تعبیهشده در MongoDB Atlas است. برنامه به طور خودکار دادهها را بین دستگاههای کاربر و سرور همگامسازی میکند. تعارضات با استراتژی «آخرین نوشتن برنده میشود» یا از طریق توابع سفارشی حل تعارض در سرور برطرف میشوند. Realm Sync از همگامسازی جزئی (subset of data) برای کاهش ترافیک پشتیبانی میکند.
class SyncRepository {
private val app = App(
AppConfiguration(
appId = "my-realm-app-id"
)
)
suspend fun syncData() {
val user = app.login(Credentials.anonymous())
val config = SyncConfiguration.Builder(
user, setOf(Project::class)
).build()
val syncedRealm = Realm.open(config)
// همگامسازی خودکار فعال است
}
}
SyncConfiguration اتصال به MongoDB Atlas را پیکربندی میکند و مجموعه مدلهای همگامشونده را تعریف میکند. پس از احراز هویت کاربر، Realm به طور خودکار دادهها را از ابر بارگیری کرده و با تغییرات محلی ترکیب میکند. همگامسازی در رشته پسزمینه کار میکند و نیازی به فراخوانی دستی ندارد — کافی است یک نمونه Realm با SyncConfiguration ایجاد کنید.
سؤالات متداول
بله، پایگاه داده محلی Realm کاملاً رایگان است (مجوز Apache 2.0). Realm Sync (همگامسازی ابری) از طریق MongoDB Atlas یک سرویس پولی است که در اشتراک Atlas Device Sync گنجانده شده است. برای سطح رایگان Atlas، ۵۰۰ مگابایت اول داده و ۱ میلیون عملیات در ماه در دسترس است.
بله، مهاجرت از طریق صادرات دادهها از SQLite به JSON و import در Realm در بارگذاری اول برنامه امکانپذیر است. برای حجمهای بزرگ از مهاجرت جریانی استفاده کنید: دادهها را به طور همزمان در هر دو پایگاه داده بنویسید تا زمانی که کاربران به نسخه جدید برنامه منتقل شوند، سپس فایل SQLite را حذف کنید.
Realm Sync به طور پیشفرض از استراتژی «آخرین نوشتن برنده میشود» استفاده میکند — آخرین نوشتن، نوشته قبلی را بازنویسی میکند. برای تعارضات پیچیده، توابع سفارشی حل تعارض را در سرور MongoDB Atlas پیکربندی کنید که تغییرات دستگاههای مختلف را بر اساس منطق تجاری برنامه ترکیب میکند (مثلاً ادغام مقادیر به جای جایگزینی).
Realm از تجمیعهای SQL (SUM، AVG، GROUP BY) در سطح پایگاه داده پشتیبانی نمیکند. برای کوئریهای تحلیلی، توصیه میشود دادهها را از طریق Realm Sync به MongoDB Atlas منتقل کرده و تجمیعها را از طریق MongoDB Aggregation Pipeline انجام دهید. برای شمارشهای ساده از realm.query<T>().count() استفاده کنید.
Realm دادهها را به طور پیشفرض رمزنگاری نمیکند. برای رمزنگاری، یک کلید ۶۴ بایتی در پیکربندی مشخص کنید: Realm.Configuration(encryptionKey: key). رمزنگاری از AES-256 + SHA-2 HMAC استفاده میکند و سربار عملیات را ۱۰-۲۰٪ افزایش میدهد. بدون رمزنگاری، فایل .realm توسط هر فرآیندی با دسترسی به سیستم فایل قابل خواندن است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید