当前位置:首页 > 行业动态 > 正文

安卓开发之数据库设计

安卓数据库选型

数据库类型 特点 适用场景
SQLite 轻量级嵌入式数据库,支持SQL语法,无需独立服务器 本地数据存储(如用户配置、缓存)
Room 基于SQLite的抽象层,提供编译时校验,支持LiveData 需要与架构组件(如ViewModel)联动的复杂业务
Realm 面向对象的数据库,高性能,跨平台支持 频繁读写的实时数据(如IoT应用)

数据库设计核心原则

  1. 数据规范化

    • 遵循三范式:消除重复字段、确保依赖关系合理
    • 示例:用户表(user_id, username) 与订单表(order_id, user_id) 通过外键关联
  2. 字段类型优化
    | 数据类型 | 适用场景 | 安卓对应类型 |
    |———|———-|————–|
    | TEXT | 字符串(如用户名) | String |
    | INTEGER | 整数(如年龄) | Int |
    | REAL | 浮点数(如经纬度) | Double |
    | BLOB | 二进制数据(如图片)| byte[] |

  3. 主键策略

    • 自增主键:适用于需要唯一标识的场景(如订单号)
    • UUID主键:分布式系统中防止冲突(如多设备同步)

Room数据库实战设计

// 1. 定义实体类
@Entity(tableName = "users")
data class User(
    @PrimaryKey(autoGenerate = true) val id: Int,
    @ColumnInfo(name = "username") val name: String,
    @ColumnInfo(name = "create_time") val createTime: Long
)
// 2. 创建DAO接口
@Dao
interface UserDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUser(user: User)
    @Query("SELECT  FROM users WHERE id = :userId")
    fun getUserById(userId: Int): LiveData<User>
}
// 3. 构建数据库
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

数据库操作关键API

操作类型 Room API 说明
插入数据 insert() 支持冲突策略(REPLACE/ABORT)
更新数据 update() 需配合@Query使用
删除数据 delete() 支持条件删除
查询数据 @Query 支持返回LiveData/Flow

常见问题解决方案

数据库版本升级

安卓开发之数据库设计  第1张

// 1. 修改@Database注解的version属性
@Database(version = 2) // 从1升级到2
// 2. 实现Migration接口
val MIGRATION_1_2 = object : Migration(1, 2) {
    override fun migrate(database: SupportSQLiteDatabase) {
        database.execSQL("ALTER TABLE users ADD COLUMN age INTEGER")
    }
}
// 3. 构建数据库时传入迁移对象
Room.databaseBuilder(context, AppDatabase::class.java, "app.db")
    .addMigrations(MIGRATION_1_2)
    .build()

大数据量分页查询

@Dao
interface LargeDataDao {
    @Query("SELECT  FROM data_table LIMIT :limit OFFSET :offset")
    fun getPagedData(limit: Int, offset: Int): List<Data>
}

性能优化技巧

  1. 索引优化

    • 对高频查询字段建立索引(如CREATE INDEX idx_username ON users(username)
    • 注意过多索引会影响写入性能
  2. 事务处理

    @Transaction
    suspend fun updateUsers(users: List<User>) {
        userDao.deleteAll()
        userDao.insertUsers(users)
    }
  3. 内存缓存结合

    • 使用@Query("SELECT FROM users")配合LiveData实现自动更新
    • 重要数据可额外使用SharedPreferences缓存

【相关问题解答】

Q1:SQLite和Room应该如何选择?
答:SQLite适合简单场景(如仅需CRUD操作),可直接使用SQLiteOpenHelper,Room更适合复杂业务场景,其优势包括:

  • 编译时校验SQL语句正确性
  • 自动生成DAO接口实现
  • 内置支持LiveData/Flow响应式编程
  • 提供迁移工具和类型安全机制

Q2:如何处理一对一/一对多的表关系?
答:

  1. 一对一关系:合并表结构或使用FOREIGN KEY约束

    -用户表与详情表一对一
    CREATE TABLE user_details (
        id INTEGER PRIMARY KEY,
        user_id INTEGER,
        bio TEXT,
        FOREIGN KEY(user_id) REFERENCES users(id)
    )
  2. 一对多关系:在”多”方表中添加外键字段

    // Order表(多方)包含user_id外键
    @Entity
    data class Order(
        @PrimaryKey val orderId: Int,
        val userId: Int, // 关联用户表的主键
        val amount: Double
    )
0