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

安卓应用开发数据库设计

数据库选型分析

方案 适用场景 特点
SQLite 本地轻量级存储 文件型数据库,支持ACID,适合结构化数据,无需独立服务器
Room 需要架构组件集成的SQLite 提供抽象层,支持LiveData/Coroutines,编译时验证SQL正确性
Realm 高性能对象存储 支持复杂查询,跨平台,但学习成本较高
Firebase Firestore 实时同步的云端存储 自动离线缓存,全球部署,按使用量计费
SharedPreferences 键值对存储 仅适合简单配置数据,无查询能力

表结构设计规范

示例:用户信息表(users)
| 字段名 | 数据类型 | 主键/索引 | 约束条件 | 说明 |
|————–|————-|———-|——————–|——————————-|
| uId | INTEGER | PRIMARY KEY AUTOINCREMENT | 自增主键 |
| username | TEXT | UNIQUE | NOT NULL | 30字符以内唯一用户名 |
| passwordHash | TEXT | | NOT NULL | SHA-256加密存储 |
| email | TEXT | UNIQUE | NOT NULL | 邮箱格式校验 |
| createTime | LONG | | NOT NULL | 时间戳(1970基准毫秒数) |
| lastLogin | LONG | | | 最近登录时间 |
| status | INTEGER | | DEFAULT 0 | 0:正常 1:封禁 |

索引优化策略

  1. 必要索引

    • 主键自动创建唯一索引
    • 频繁查询的WHERE条件字段(如email/username)
    • ORDER BY/GROUP BY涉及的字段
  2. 复合索引

    CREATE INDEX idx_user_status_time ON users(status, createTime);
  3. 避免过度索引

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

    • 每新增一个索引会降低写操作性能
    • 优先为高频查询路径创建索引

数据库版本管理

版本号 升级操作 注意事项
1 初始创建users表
2 新增lastLogin字段 ALTER TABLE操作需谨慎
3 修改passwordHash长度限制 需迁移现有数据
4 添加消息表并建立外键关联 先创建新表再处理关联数据

Room实战要点

  1. 实体类定义

    @Entity(tableName = "users", indices = {@Index(value = {"email"}, unique = true)})
    public class User {
        @PrimaryKey(autoGenerate = true)
        public int uId;
        @ColumnInfo(name = "username", collation = ColumnInfo.COLLATION_NOCASE)
        public String username;
        // 其他字段及关系注解...
    }
  2. DAO层方法

    @Dao
    public interface UserDao {
        @Query("SELECT  FROM users WHERE status = :status ORDER BY lastLogin DESC")
        List<User> getActiveUsers(int status);
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        long insertUser(User user);
        @Update
        void updateLoginTime(String email, long time);
    }
  3. 数据库构建器

    public class AppDatabase extends RoomDatabase {
        private static final String MIGRATION_FROM_2_TO_3 = "MIGRATION_2_3";
        static {
            Room.migrationsEnabled(true); // Android P+ 必须显式开启
        }
        private static volatile AppDatabase INSTANCE;
        public static AppDatabase getInstance(Context context) {
            if (INSTANCE == null) {
                synchronized (AppDatabase.class) {
                    INSTANCE = Room.databaseBuilder(context, AppDatabase.class, "app.db")
                        .addMigrations(new Migration_2_3())
                        .build();
                }
            }
            return INSTANCE;
        }
    }

数据安全措施

  1. 静态加密

    // 在Room配置中启用加密
    .openHelperFactory(factory) // factory实现AES加密逻辑
  2. 动态防护

    • 敏感字段前端模糊处理(如手机号显示)
    • SQL注入防护:使用参数化查询代替字符串拼接
    • 关键操作二次验证(如删除数据前弹窗确认)

常见问题与解决方案

Q1:数据库升级导致应用崩溃

  • 原因:未处理版本迁移,新旧表结构不兼容
  • 解决方案
    1. Room.databaseBuilder中添加.fallbackToDestructiveMigration()(慎用,会清空数据)
    2. 编写Migration脚本:
      static final Migration MIGRATION_3_4 = new Migration(3, 4) {
          @Override
          public void migrate(@NonNull SupportSQLiteDatabase db) {
              db.execSQL("ALTER TABLE users ADD COLUMN phone TEXT");
              // 处理默认值和数据迁移逻辑
          }
      };

Q2:多表关联查询性能低下

  • 原因:缺乏有效索引或N+1查询问题
  • 优化方案
    • 使用@Transaction注解批量查询关联数据
    • 在DAO层预加载关联数据:
      @Transaction
      @Query("SELECT  FROM orders WHERE userId = :userId")
      List<Order> getOrdersWithUser(String userId);
0