OStack程序员社区-中国程序员成长平台

标题: ios - Realm 是什么样的数据库? [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 12:56
标题: ios - Realm 是什么样的数据库?

Realm 是什么类型的数据库?是 ORM 吗?还是它像对象数据库一样工作?也许数据库结构会以某种方式影响设计过程?设计 Realm 数据库有什么细微差别吗?

我在这里问,因为我在官网上没有找到答案



Best Answer-推荐答案


不幸的是,我实际上并没有使用 iOS 版本,但我使用的是 Android 版本,它的功能集与 iOS 版本越来越相似,并且他们共享相同的 core,它们更接近于通过 object-store 提供相同的统一行为。

因此,此答案的大部分将基于 Swift API 文档。 (境界迅捷 2.6.1)


Realm 默认是一个对象存储。从技术上讲,它将您的数据存储在架构中,其中架构由类定义,例如

// from https://realm.io/docs/swift/latest/#models
class Person: Object {
    dynamic var name = ""
    dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
    let dogs = List<Dog>()
}

Realm 的有趣之处在于它不是一个关系型数据库。它直接存储对象。实际上,由 Realm 管理的对象(也就是通过对 Realm 的查询获得的,或者由 Realm 创建的新对象)直接映射到底层 Realm 文件,并且不会将数据复制到字段,访问器直接读取和写入 Realm 文件。

这种“直接访问”导致所有数据仅在访问时加载(延迟评估),因此不需要缓存托管对象(!)。

所有写入都是事务性的。在事务之外,托管的 RealmObjects 不能被修改。


在您的对象之间,您可以拥有关系(链接):

// from https://realm.io/docs/swift/latest/#relationships
class Dog: Object {
    // ... other property declarations
    dynamic var owner: Person? // to-one relationships must be optional
}

class Person: Object {
    // ... other property declarations
    let dogs = List<Dog>() // to-many relationship
}

任何关系(一对一、对多)都有其对应的backlink,您可以将其定义为“链接到该对象的对象”。

// from https://realm.io/docs/swift/latest/#relationships
class Dog: Object {
    dynamic var name = ""
    dynamic var age = 0
    let owners = LinkingObjects(fromType: Person.self, property: "dogs")
}

Realm 的托管对象是“实时的、不可变的数据 View ”(来自 here),它在原地发生变异,并且您通过 通知 token (来自 here)。这同样适用于任何托管的 RealmObject,但也适用于查询结果

意思是,查询结果会自动进行异步评估,并且只有在给定索引处访问的元素才会以延迟加载的方式从数据库中读取!因此,不需要分页。

任何线程上的任何写入都会自动向与运行循环关联的线程发送通知,查询结果会自动更新,并调用更改监听器(通知 block )。

// from https://realm.io/docs/swift/latest/#collection-notifications
  override func viewDidLoad() {
    super.viewDidLoad()
    let realm = try! Realm()
    let results = realm.objects(Person.self).filter("age > 5")

    // Observe Results Notifications
    notificationToken = results.addNotificationBlock { [weak self] (changes: RealmCollectionChange) in
      guard let tableView = self?.tableView else { return }
      switch changes {
      case .initial:
        // Results are now populated and can be accessed without blocking the UI
        tableView.reloadData()
        break
      case .update(_, let deletions, let insertions, let modifications):
        // Query results have changed, so apply them to the UITableView
        tableView.beginUpdates()
        tableView.insertRows(at: insertions.map({ IndexPath(row: $0, section: 0) }),
                           with: .automatic)
        tableView.deleteRows(at: deletions.map({ IndexPath(row: $0, section: 0)}),
                           with: .automatic)
        tableView.reloadRows(at: modifications.map({ IndexPath(row: $0, section: 0) }),
                           with: .automatic)
        tableView.endUpdates()
        break
      case .error(let error):
        // An error occurred while opening the Realm file on the background worker thread
        fatalError("\(error)")
        break
      }
    }
  }

  deinit {
    notificationToken?.stop()
  }

最广为人知的限制是 RealmObjects、RealmResults 和 Realms不能在线程之间传递。 (其他限制为 here)。

给定线程上的 RealmObject/RealmResults/Realm 只能在打开其对应 Realm 实例的线程上访问(读取 here)。 (异常(exception)情况是使用 ThreadSafeReference 在线程之间发送 RealmObjects,参见 here

因此,后台线程需要自己的 Realm 实例,通常包装在 autoreleasepool 中,参见 here .

// from https://realm.io/docs/swift/latest/#using-a-realm-across-threads
DispatchQueue(label: "background").async {
  autoreleasepool {
    // Get realm and table instances for this thread
    let realm = try! Realm()

    // Break up the writing blocks into smaller portions
    // by starting a new transaction
    for idx1 in 0..<1000 {
      realm.beginWrite()

      // Add row via dictionary. Property order is ignored.
      for idx2 in 0..<1000 {
        realm.create(Person.self, value: [
          "name": "\(idx1)",
          "birthdate": Date(timeIntervalSince1970: TimeInterval(idx2))
        ])
      }

      // Commit the write transaction
      // to make this data available to other threads
      try! realm.commitWrite()
    }
  }
}

关于ios - Realm 是什么样的数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42337312/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4