Realm là cơ sở dữ liệu NoSQL hướng đối tượng dành cho thiết bị di động, được phát triển như một giải pháp thay thế cho SQLite và Core Data trên iOS và Android. Dữ liệu được lưu trữ ở định dạng riêng với quyền truy cập trực tiếp vào các đối tượng trong bộ nhớ, mang lại tốc độ đọc và ghi cao. Nhờ thông báo phản ứng, đồng bộ hóa tự động qua Realm Sync và mô hình dữ liệu đa nền tảng, Realm được sử dụng trên hơn 1 tỷ thiết bị (dữ liệu MongoDB, 2025).
Những điểm chính
Realm là cơ sở dữ liệu hướng đối tượng được tạo ra đặc biệt cho các ứng dụng di động. Không giống như SQLite, Realm không sử dụng SQL hay mô hình quan hệ — dữ liệu được lưu trữ dưới dạng đối tượng sống (Live Objects), có thể truy cập trực tiếp mà không qua lớp ORM trung gian. Nhà phát triển làm việc với các đối tượng ngôn ngữ thông thường (Swift, Kotlin, Dart) được tự động lưu vào cơ sở dữ liệu.
Realm xuất hiện vào năm 2014 với tư cách là startup Realm Inc., và vào năm 2019 được MongoDB Inc. mua lại. Kể từ đó, Realm được phát triển với tên MongoDB Realm — một phần của nền tảng hợp nhất Atlas Device Sync để đồng bộ hóa dữ liệu di động. Cơ sở dữ liệu cục bộ cơ bản của Realm vẫn miễn phí và mã nguồn mở (giấy phép Apache 2.0), trong khi Realm Sync (đồng bộ hóa đám mây) được phân phối theo gói đăng ký.
Theo MongoDB Developer Report (2025), Realm được sử dụng trong 15% ứng dụng di động làm bộ lưu trữ cục bộ chính. Các trường hợp sử dụng chính là ứng dụng có chế độ ngoại tuyến, mô hình đối tượng phức tạp và nhu cầu đồng bộ hóa giữa các thiết bị, nơi Realm vượt trội hơn SQLite về tốc độ phát triển và dễ dàng làm việc với các đối tượng.
Live Objects — mỗi đối tượng Realm được liên kết với đĩa thông qua tệp ánh xạ bộ nhớ (memory-mapped file). Thay đổi một đối tượng trong bất kỳ luồng nào sẽ ngay lập tức phản ánh trong tất cả các luồng khác mà không cần thông báo thủ công. Giao diện người dùng tự động vẽ lại khi dữ liệu thay đổi thông qua thông báo Realm. Zero-copy — Realm không sao chép dữ liệu từ cơ sở dữ liệu vào đối tượng; các đối tượng chính là dữ liệu trong bộ nhớ.
Lõi Realm được viết bằng C++ và sử dụng B+ Tree để lập chỉ mục dữ liệu. Không giống SQLite, nơi mỗi hàng là một bản ghi trong bảng quan hệ, Realm lưu trữ các đối tượng dưới dạng nút trong cấu trúc đồ thị với các tham chiếu trực tiếp giữa chúng (forward pointers). Mối quan hệ giữa các đối tượng không phải là khóa ngoại mà là con trỏ trực tiếp, loại bỏ nhu cầu về các thao tác JOIN.
Các tệp Realm (phần mở rộng .realm) được ánh xạ bộ nhớ (memory-mapped) — hệ điều hành tự quản lý việc tải các trang tệp vào bộ nhớ khi được truy cập. Điều này cho phép Realm làm việc với cơ sở dữ liệu lớn hơn RAM khả dụng và cung cấp độ trễ đọc ở cấp độ cấu trúc dữ liệu ngôn ngữ gốc (Swift Array hoặc Kotlin List) cho dữ liệu nằm vừa trong RAM.
Tệp ánh xạ bộ nhớ — công nghệ chính của Realm. Thay vì sao chép dữ liệu từ tệp cơ sở dữ liệu vào các đối tượng ngôn ngữ (như SQLite làm qua sqlite3_step + sqlite3_column_*), Realm ánh xạ trực tiếp tệp cơ sở dữ liệu vào không gian địa chỉ của tiến trình. Các đối tượng ngôn ngữ chỉ đơn giản là con trỏ đến dữ liệu trong bộ nhớ được ánh xạ. Thay đổi một đối tượng sẽ sửa đổi cơ sở dữ liệu trên đĩa mà không cần gọi save riêng.
| Đặc điểm | Realm (zero-copy) | SQLite (sao chép) |
|---|---|---|
| Đọc | Truy cập bộ nhớ trực tiếp (nanô giây) | Sao chép vào đối tượng (micrô giây) |
| Ghi | Ghi ngay vào tệp memory-mapped | save() với giao dịch SQL INSERT/UPDATE |
| Quan hệ | Con trỏ trực tiếp (forward pointers) | Khóa ngoại + JOIN |
| Tiêu thụ bộ nhớ | Tệp + bộ đệm trang HĐH | Đối tượng + bộ đệm trang SQLite |
| Đối tượng sống | Có (cập nhật tự động) | Không (cần truy vấn mới) |
Tiêu thụ bộ nhớ cao hơn ở Realm khi đọc tích cực (toàn bộ tệp hoặc phần lớn được ánh xạ vào bộ nhớ), nhưng thấp hơn khi ghi vì không cần cấp phát bộ nhớ cho các bản sao đối tượng. Đối với cơ sở dữ liệu lên tới 1 GB trên thiết bị di động, phương pháp ánh xạ bộ nhớ mang lại hiệu suất tổng thể tốt hơn SQLite với bản sao trung gian.
SQLite là hệ quản trị cơ sở dữ liệu quan hệ với SQL và giao dịch ACID. Realm là cơ sở dữ liệu NoSQL hướng đối tượng với truy cập ánh xạ bộ nhớ. Core Data là lớp ORM của Apple trên SQLite. Mỗi phương pháp trong ba phương pháp đều có lĩnh vực ứng dụng và điểm mạnh riêng. Realm vượt trội về tốc độ truy cập đối tượng trực tiếp và khả năng phản ứng, SQLite về tính linh hoạt và độ chín muồi, Core Data về tích hợp với hệ sinh thái Apple.
Hiệu suất đọc của Realm cao hơn SQLite 10-50% nhờ truy cập zero-copy. Realm cũng nhanh hơn khi ghi do không cần phân tích cú pháp SQL và sửa đổi trực tiếp các trang ánh xạ bộ nhớ. Tuy nhiên, Realm có thể tiêu thụ nhiều RAM hơn khi làm việc với cơ sở dữ liệu lớn (>500 MB), vì tệp được ánh xạ hoàn toàn vào không gian địa chỉ.
| Tiêu chí | Realm | SQLite | Core Data |
|---|---|---|---|
| Loại | DB NoSQL hướng đối tượng | Hệ QTCSDL quan hệ (SQL) | ORM trên SQLite |
| Tốc độ đọc | Cao (zero-copy) | Trung bình | Trung bình (chi phí ORM) |
| Khả năng phản ứng | Live Objects (tích hợp) | Cần wrapper (Room/GRDB) | NSFetchedResultsController |
| Đồng bộ hóa | Realm Sync (MongoDB Atlas) | Cần tự triển khai | NSPersistentCloudKitContainer |
| Nền tảng | iOS, Android, Flutter, RN, Node.js | iOS, Android, Web, Máy tính | Chỉ iOS/macOS |
| Kích thước thư viện | ~4 MB | ~600 KB | Tích hợp trong SDK |
Sự lựa chọn giữa Realm và SQLite thường phụ thuộc vào ưu tiên: tốc độ phát triển và khả năng phản ứng (Realm) so với kiểm soát và tính linh hoạt (SQLite). Realm đặc biệt tốt cho MVP và nguyên mẫu nơi mô hình dữ liệu thay đổi thường xuyên và việc nhận cập nhật giao diện trực tiếp nhanh chóng là quan trọng. SQLite/Room phù hợp hơn cho các sản phẩm trưởng thành với khối lượng dữ liệu lớn và truy vấn phân tích phức tạp.
Realm Kotlin SDK là thư viện chính thức cho Android, được viết bằng Kotlin (không phải wrapper trên Java SDK). Mô hình dữ liệu được xác định thông qua các lớp kế thừa từ RealmObject, với chú thích @PrimaryKey cho định danh duy nhất. Realm Kotlin hỗ trợ Kotlin Coroutines, Flow và KSP (Kotlin Symbol Processing) để tạo mã tại thời điểm biên dịch.
RealmQuery cung cấp API an toàn kiểu để lọc mà không cần SQL. Truy vấn được xây dựng thông qua chuỗi phương thức: query → filter → sort → find. Kết quả có thể được trả về dưới dạng danh sách (tải vào bộ nhớ) hoặc Flow (luồng phản ứng cập nhật khi dữ liệu thay đổi). Realm Kotlin cũng hỗ trợ các đối tượng lồng nhau và danh sách (RealmList).
Mô hình dữ liệu Realm được định nghĩa như một lớp dữ liệu triển khai giao diện RealmObject. Trường _id được đánh dấu bằng @PrimaryKey để nhận dạng duy nhất. Mối quan hệ một-nhiều được triển khai qua RealmList — danh sách các RealmObject khác. Tất cả các thao tác ghi (tạo, cập nhật, xóa) được thực hiện trong khối giao dịch 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()
Truy vấn trả về Flow tự động phát ra kết quả mới khi có bất kỳ thay đổi dữ liệu nào trong Realm: thêm, cập nhật hoặc xóa Project hoặc Task. Phương pháp Flow kết hợp hoàn hảo với Compose: collectAsState() trong ViewModel tự động tái tạo giao diện khi dữ liệu thay đổi mà không cần cập nhật thủ công bộ điều hợp danh sách hoặc sử dụng LiveData.
Realm Swift SDK cung cấp API Swift gốc với hỗ trợ async/await, Combine Publishers và Swift Concurrency. Các mô hình dữ liệu được định nghĩa dưới dạng lớp kế thừa từ Object, sử dụng @Persisted cho các thuộc tính. Realm Swift tự động cập nhật đối tượng khi có thay đổi và thông báo (NotificationToken) cho phép đăng ký thay đổi của từng đối tượng hoặc bộ sưu tập.
@ObservedRealmObject và @ObservedResults là các Property Wrapper cho SwiftUI tự động vẽ lại View khi dữ liệu Realm thay đổi. @ObservedResults làm việc với kết quả truy vấn, @ObservedRealmObject với đối tượng cụ thể. Cả hai thuộc tính đều hủy đăng ký khi View bây giờ bị hủy khởi tạo.
Tích hợp SwiftUI Realm là một trong những điểm mạnh của SDK. Property Wrapper @ObservedResults liên kết truy vấn Realm với hiển thị SwiftUI. Khi bất kỳ tác vụ nào thay đổi, SwiftUI tự động tái tạo danh sách. realm.writeAsync thực hiện các giao dịch trên luồng nền mà không chặn giao diện.
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("Add Task") {
let realm = try! Realm()
try! realm.write {
realm.add(TaskItem(value: ["title": "New task"]))
}
}
}
}
@ObservedResults tự động quản lý vòng đời truy vấn Realm: khi View được tạo, đăng ký thay đổi được tạo; khi bị hủy, nó bị hủy bỏ. Property Wrapper chấp nhận một vị từ tùy chọn (NSPredicate) và bộ mô tả sắp xếp. Điều này loại bỏ nhu cầu viết thủ công các yêu cầu tìm nạp, tạo ViewModel và đăng ký thông báo Realm.
Ứng dụng ngoại tuyến — Realm lý tưởng cho các tình huống dữ liệu phải khả dụng mà không cần internet. Đồng bộ hóa tích hợp (Realm Sync với MongoDB Atlas) tự động giải quyết xung đột khi kết nối mạng. Ứng dụng tiếp tục hoạt động với dữ liệu cục bộ và đồng bộ hóa nền cập nhật dữ liệu khi có kết nối.
Giao diện phản ứng — Live Objects và thông báo Flow/Combine làm cho Realm trở thành lựa chọn thuận tiện cho các ứng dụng có dữ liệu thường xuyên cập nhật: trò chuyện, luồng tác vụ, tài liệu cộng tác. Giao diện tự động cập nhật khi dữ liệu được thêm, thay đổi hoặc xóa mà không cần gọi thủ công reloadData hoặc invalidate.
Dự án đa nền tảng — Realm hỗ trợ Kotlin Multiplatform (KMP), Flutter, React Native và Xamarin. Mô hình dữ liệu được xác định một lần và sử dụng trên tất cả các nền tảng. Điều này giảm trùng lặp mã và đảm bảo tính nhất quán lược đồ giữa ứng dụng iOS và Android có logic kinh doanh chung.
Realm Sync là dịch vụ đám mây được tích hợp trong MongoDB Atlas. Ứng dụng tự động đồng bộ hóa dữ liệu giữa thiết bị của người dùng và máy chủ. Xung đột được giải quyết bằng chiến lược "last write wins" hoặc thông qua các hàm giải quyết xung đột tùy chỉnh trên máy chủ. Realm Sync hỗ trợ đồng bộ hóa một phần (tập con dữ liệu) để giảm lưu lượng.
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)
// Đồng bộ hóa tự động đang hoạt động
}
}
SyncConfiguration cấu hình kết nối đến MongoDB Atlas và xác định tập hợp các mô hình cần đồng bộ hóa. Sau khi người dùng xác thực, Realm tự động tải dữ liệu từ đám mây và hợp nhất với các thay đổi cục bộ. Đồng bộ hóa chạy trên luồng nền và không yêu cầu gọi thủ công — chỉ cần tạo phiên bản Realm với SyncConfiguration.
Câu hỏi thường gặp
Có, cơ sở dữ liệu cục bộ Realm hoàn toàn miễn phí (giấy phép Apache 2.0). Realm Sync (đồng bộ hóa đám mây) qua MongoDB Atlas là dịch vụ trả phí trong gói đăng ký Atlas Device Sync. Gói miễn phí Atlas bao gồm 500 MB dữ liệu đầu tiên và 1 triệu thao tác mỗi tháng.
Có, di chuyển có thể thực hiện bằng cách xuất dữ liệu từ SQLite sang JSON và nhập vào Realm khi ứng dụng khởi chạy lần đầu. Đối với khối lượng lớn, hãy sử dụng di chuyển luồng: ghi dữ liệu vào cả hai cơ sở dữ liệu song song trong khi người dùng chuyển sang phiên bản ứng dụng mới, sau đó xóa tệp SQLite.
Realm Sync mặc định sử dụng chiến lược "last write wins" — lần ghi cuối cùng ghi đè lần ghi trước. Đối với xung đột phức tạp, hãy cấu hình các hàm giải quyết xung đột tùy chỉnh trên máy chủ MongoDB Atlas để hợp nhất các thay đổi từ các thiết bị khác nhau theo logic kinh doanh của ứng dụng (ví dụ: hợp nhất giá trị thay vì thay thế).
Realm không hỗ trợ tổng hợp SQL (SUM, AVG, GROUP BY) ở cấp cơ sở dữ liệu. Đối với truy vấn phân tích, nên xuất dữ liệu từ Realm sang MongoDB Atlas qua Realm Sync và thực hiện tổng hợp qua MongoDB Aggregation Pipeline. Đối với đếm đơn giản, hãy sử dụng realm.query<T>().count().
Realm không mã hóa dữ liệu theo mặc định. Để mã hóa, hãy cung cấp khóa 64 byte trong cấu hình: Realm.Configuration(encryptionKey: key). Mã hóa sử dụng AES-256 + SHA-2 HMAC và tăng chi phí thao tác lên 10-20%. Nếu không mã hóa, tệp .realm có thể được đọc bởi bất kỳ tiến trình nào có quyền truy cập hệ thống tệp.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm