所感箱

所感を書きためていきます

Androidのローカルデータベースの選択肢の整理

この記事はコネヒトアドベントカレンダー2022の13日目の記事です。

Androidでローカルデータベースの選択肢を整理してみた。

最初に結論

  • Realmは更新の速度は優秀だが、アプリサイズや参照メソッド数の考慮が必要
  • Androidだけの環境ならRoomを選択する方が無難に思う
  • iOSAndroidマルチプラットフォームの構想があるならRealmもあり

※他にもいい選択肢があれば教えてください!

デベロッパーガイドはRoomの利用を強く推奨している

Androidでローカルデータベースを選択する場合、Room or Realmが選択肢に上がることが多いと思う。

もちろんSQLiteを生で実装することも、可能ではあるが学習コストの高さを軽減したり、安定的な開発をするために、デベロッパーガイドではRoomを利用することが推奨されている。

数年前では、Realmを利用することが多かったイメージだが、Roomが実装されたことにより、トレンドが大きく動いたと感じている。この2つについて改めて整理してみた。

RealmとRoomの比較は下の記事を参考にさせてもらった。

itnext.io

参照メソッド数とアプリサイズ

RoomとRealmの参照されるメソッドは、Roomがはるかに少なかった。Realmの場合はMultiDexやアプリサイズへの影響を考慮する必要がありそうだった。

Room

Realm

アプリサイズ

加えて、Realmはネイティブライブラリが含まれるため、アプリサイズへの影響もありそうだった

複数スレッドでの操作

RoomはRoomDatabase.Builder.setTransactionExecutor(Executor)を指定することで、複数スレッドからのトランザクションを抑制できるとのことで、それ以降のバージョンを使うほうが余計な考慮はせず済みそうだった。

developer.android.com

対してRealmはKotlinのSDKのみスレッドセーフな実装になっている様子。

www.mongodb.com

速度面

触ってみるついでに、1万件のクラスを作りそれぞれ全件取得するコードを書いて速度を比較してみた。

Room

@Entity
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String?,
    @ColumnInfo(name = "last_name") val lastName: String?
)

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>
}

val db = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java, "database-name"
            ).build()
val userDao = db.userDao()

userDao.getAll()

Realm

class Person : RealmObject {
    var name: String = "Foo"
}

val configuration = RealmConfiguration.create(schema = setOf(Person::class))
val realm = Realm.open(configuration)

realm.query<Person>().find().forEach {
    // nop
}

結果

挿入と参照の速度。単位はミリ秒。

このような使い方をすることはないので、あくまでも参考情報だが、10万件の全件取得だとRoomの方が速度が速かった。RoomはgetAllで全件を一度に取得する設計に対して、RealmはfindではRealmResultで参照を持ち、アクセス時に実体を取得する設計のようだった。

試しに1件だけ更新したところ以下のようにRomの方が高速で処理がなされていた。

更新の速度。単位はナノ秒

じゃあ、どっちを使う?

性能面の比較をしてみたが、Realmではもう一つ重要な観点があった。

RealmはKMMでのSDKが提供されているため、iOSAndroidでのマルチプラットフォームを狙う場合は、選択肢としては強い動機になりうると思った。

www.mongodb.com

KotlinSDKはマルチプラットフォーム対応

結論