Какую БД выбрать в Android новичку: короткий ответ и план действий
Выберите Room — для 90% приложений это проще, безопаснее и быстрее в разработке; SQLite оставьте для учебных экспериментов или очень лёгких прототипов. Ниже — сравнение, реальные плюсы/минусы и пошаговый план запуска CRUD с Room за 30–60 минут.
Зачем нужна локальная база и когда выбирать SQLite/Room
Локальная БД нужна, если данные должны сохраняться между запусками: заметки, настройки, кэш, профили. SQLite — встроенная реляционная СУБД без сервера; Room — современный ORM-слой Jetpack поверх SQLite, который убирает boilerplate и даёт type-safety и интеграцию с LiveData/Flow/Coroutines.
Room ловит многие ошибки SQL на этапе компиляции и автоматически обновляет UI через LiveData/Flow — идеален для быстрых и устойчивых прототипов.
Краткое сравнение (что важно для новичка)
| Критерий | SQLite (ручной) | Room (Jetpack) |
|---|---|---|
| Сложность | средняя: SQLiteOpenHelper и SQL | низкая: аннотации и сгенерированный код |
| Type-safety | нет | да (ошибки на compile-time) |
| Асинхронность | вручную | встроенная (suspend, Flow, LiveData) |
| APK‑вес | 0 доп. | +2–5 МБ |
| Рекомендация | быстрый прототип за час | любое реальное приложение, удобнее масштабировать |
Быстрый старт с Room — пошагово (Kotlin)
- Создайте проект: New Project → Empty Activity, Kotlin, minSdk 24+.
- Добавьте зависимости (module build.gradle.kts):
val room_version = "2.6.1"
implementation("androidx.room:room-runtime:$room_version")
implementation("androidx.room:room-ktx:$room_version")
kapt("androidx.room:room-compiler:$room_version")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3")
- Entity:
@Entity(tableName = "users")
data class User(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val name: String,
val age: Int
)
- Dao:
@Dao
interface UserDao {
@Query("SELECT * FROM users") fun getAll(): LiveData<List<User>>
@Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(user: User)
@Delete suspend fun delete(user: User)
}
- Database:
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
- ViewModel и использование:
class UserViewModel(app: Application): AndroidViewModel(app) {
private val db = Room.databaseBuilder(app, AppDatabase::class.java, "db").build()
val users: LiveData<List<User>> = db.userDao().getAll()
suspend fun add(user: User) = db.userDao().insert(user)
}
В Activity/Fragment — observe(users) и запуск insert в coroutine (viewModelScope.launch).
Нельзя выполнять запросы Room в UI‑потоке: используйте suspend, Flow или LiveData и корутины/Dispatchers.IO.
Частые ошибки новичков
- Забытые миграции при изменении схемы → падение при обновлении: добавляйте Migration или fallbackToDestructiveMigration только в ранних прототипах.
- Блокировка main‑thread: даже SELECT надо выполнять асинхронно.
- Отсутствие индексов на часто фильтруемые поля → медленные запросы.
- Неверные типы в Entity → NULL/потеря данных. Используйте non-nullable типы и конвертеры (TypeConverters).
FAQ
- Нужно ли учить SQL? Да — базовый SQL помогает при сложных запросах, но для большинства CRUD Room с @Query и DAO хватает.
- Можно ли подключить существующий .db? Да — Room поддерживает prepackaged databases (createFromAsset/createFromFile) и миграции.
- Когда SQLite предпочтительнее? Для минимальных задач без зависимости от Jetpack или при изучении ядра БД.
Заключение: начните с Room — быстро получите рабочий, безопасный и масштабируемый код. Поиграйте с SQLite, чтобы понять низкоуровневые механизмы, но для реальных приложений выбирайте Room. Удачи в разработке!