gpt4 book ai didi

android - 使用带有 Android 的 Room 使用 UUID 作为主键

转载 作者:行者123 更新时间:2023-12-03 17:12:37 24 4
gpt4 key购买 nike

我需要将我的 Android 移动应用程序与云中的 Multi-Tenancy 数据库同步。我认为最好的方法是使用 UUID 作为表的主键。我刚开始使用 Room 并且想知道我可以在哪里/如何做到这一点,并且正在寻找 1)关于将 UUID 用作 Room 的 PK 的意见和 2)我将在哪里实现这个(在模型中初始化 id 列,因为这是使用@NonNull 的唯一方法)?
更新
我使用过 INT,但我不相信这是正确的方法。我看到了 example来自显示正在使用 uuid 的 android 开发者网站。当然会帮助我的云同步程序,但会牺牲速度和空间。我正在考虑一种混合方法,其中 INT 用于 PK,但 UUID 作为附加字段。这样我就不必为 FK 复制每个 UUID。我做了一些建模,看起来混合方法将是完整 UUID 方法大小的 50%(INT 只有 25%)。
有没有人在同样的问题上苦苦挣扎?您是否选择了一个方向(UUID、INT 或混合)并且您后悔了还是效果很好?

最佳答案

  • 您必须使用 UUID 而不是 int 作为主键的原因有很多。例如,您的应用程序是一个分布式应用程序,就像许多人使用许多设备编辑一个文档一样,您将记录每个人的编辑日志以获取版本控制功能。如果您的应用程序是集中式的(大多数情况下),最好使用 int,或者从服务器请求主键(可以是 int、long 或其他)。如果您必须使用 UUID,请使用它。否则 int 或 long 是更好的选择。
  • 最后附上一个使用UUID作为android Room主键的例子。
  • UUID 存储空间和计算速度不应该是首要考虑的,除非你遇到过这些问题(不需要过度优化)。例如:一张图片的存储空间可能在1MB左右,UUID以String的形式保存在数据库中,采用utf-8格式,最多144 Byte(int为4 Byte),约为1/7000的一张照片。在服务器端,不推荐使用 UUID 作为主键,因为服务器同时服务上万用户,同时查询的次数很多。手机CPU虽然远弱于服务器CPU,但一次只为一个用户服务。同样,在必须使用 UUID 的场景下,也无需提前考虑优化问题。

  • 书类
    @Entity(tableName = "books")
    public class Book{
    @PrimaryKey
    @NonNull
    private UUID id;
    private String title;
    private Date date;

    public Book() {
    this.id = UUID.randomUUID();
    date = new Date();
    }

    public UUID getId() {
    return id;
    }

    public void setId(UUID id) {
    this.id = id;
    }

    public String getTitle() {
    return title;
    }

    public void setTitle(String title) {
    this.title = title;
    }

    public Date getDate() {
    return date;
    }

    public void setDate(Date date) {
    this.date = date;
    }

    }
    应用数据库类
    @Database(entities = {Book.class}, version = 1, exportSchema = false)
    @TypeConverters({UUIDConverter.class, DateConverter.class})
    public abstract class AppDatabase extends RoomDatabase {
    private static AppDatabase INSTANCE;
    private static final String DATABASE_NAME = "BookDatabase";

    public abstract BookDao bookDao();

    public static void init(Context context) {
    if (INSTANCE == null) {
    INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, DATABASE_NAME).build();
    }
    }

    public static AppDatabase getINSTANCE() {
    if (INSTANCE == null) throw new IllegalStateException("init in MyApplication.class");
    return INSTANCE;
    }
    }
    转换器:转换器将 sqlite 不支持的 uuid 或其他格式转换为支持类型。
    编辑:来自 Version 2.4.0-alpha05存在 UUID 的默认转换器,它使用字节数组而不是字符串。链接 change这对于迁移很方便。
    public class UUIDConverter {

    @TypeConverter
    public static String fromUUID(UUID uuid) {
    return uuid.toString();
    }

    @TypeConverter
    public static UUID uuidFromString(String string) {
    return UUID.fromString(string);
    }
    }

    public class DateConverter {

    @TypeConverter
    public static long timestampFromDate(Date date) {
    return date.getTime();
    }

    @TypeConverter
    public static Date dateFromTimestamp(long timestamp) {
    return new Date(timestamp);
    }
    }

    关于android - 使用带有 Android 的 Room 使用 UUID 作为主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59572749/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com