我需要将我的Android移动应用程序与云中的多租户数据库同步。我认为最好的方法是使用UUID作为表的主键。我刚刚开始使用Room,并且想知道我可以在哪里/如何这样做,并且正在寻找关于使用UUID作为一个带有Room和2)的PK的意见(在初始化id列的模型中,因为这是使用@NonNull的唯一方法)?
更新
我使用了INTs,但我不相信这是正确的方法。我在android站点上看到了一个示例,它显示了正在使用的uuid。当然会帮助我的云同步例程,但牺牲速度和空间。我正在考虑一种混合方法,将INT用于PKs,但UUID作为附加字段使用。这样,我就不必为FKs复制每个UUID。我做了一些建模,看起来混合方法将是整个UUID方法的50% ( INT只有25%大)。
有没有人为同样的问题而挣扎过?你选择了一个方向(UUID,INT,或者混合),你后悔了吗?还是说它运行得很好?
发布于 2021-01-23 09:27:38
Book.class
@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;
}
}AppDatabase.class
@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或其他格式转换为支持类型。编辑:从版本2.4.0-字母05默认转换器UUID存在,这是使用字节数组,而不是字符串。链接变化,可以方便地进行迁移。
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);
}
}发布于 2020-01-03 05:16:13
UUID比使用rowid的别名更难,效率更低。您只需使用column_name INTEGER PRIMARY KEY来表示列,列是rowid的别名。
当值未给定时,SQLite将生成一个整数值。值可以达到9223372036854775807 (您也可以使用负值,这样就可以发生2次)。
使用rowid可以达到2倍的速度。
您可以指定一个值,它必须是一个整数。
问题是云中的统一性。如果应用程序没有分配价值,那么就没有问题。
如果您希望具有随机性,那么SQlite将生成一个唯一的随机值,如果不使用自动生成(只要@PrimaryKey的实体长度不长),并且使用rowid 9223372036854775807 (当到达SQLite时,查找随机值)。
如果正和负随机性想要,那么以及添加行与9223372036854775807,添加一个负值。
这就是你简单地在房间里做的方法
实体类
@Entity
public class RandomId {
@PrimaryKey
Long randomId;
String name;
public RandomId(){}
public Long getRandomId() {
return randomId;
}
public void setRandomId(Long randomId) {
this.randomId = randomId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}刀样
@Dao
public interface RandomIdDao {
@Insert
long insert(RandomId randomId);
@Query("SELECT * FROM randomid ORDER BY name")
List<RandomId> getAll();
}
@Database(version = 1,entities = {RandomId.class})
public abstract class RandomIdDatabase extends RoomDatabase {
abstract RandomIdDao randomIdDao();
}活动类
public class MainActivity extends AppCompatActivity {
RandomIdDatabase randomIdDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
randomIdDatabase = Room.databaseBuilder(this,RandomIdDatabase.class,"randomiddb")
.allowMainThreadQueries()
.addCallback(new RoomDatabase.Callback() {
@Override
public void onCreate(@NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
/* SETUP FOR positive and negative randomids */
ContentValues cv = new ContentValues();
cv.put("randomId",9223372036854775807L);
db.insert("RandomID", OnConflictStrategy.IGNORE,cv);
cv.clear();
cv.put("RandomId",-9223372036854775808L);
db.insert("RandomID", OnConflictStrategy.IGNORE,cv);
}
})
.build();
randomIdDatabase.getOpenHelper().getWritableDatabase().beginTransaction();
RandomId r = new RandomId();
for (int i = 0; i < 1000; i++) {
r.setRandomId(null);
r.setName("name" + String.valueOf(i));
randomIdDatabase.randomIdDao().insert(r);
}
randomIdDatabase.getOpenHelper().getWritableDatabase().setTransactionSuccessful();
randomIdDatabase.getOpenHelper().getWritableDatabase().endTransaction();
List<RandomId> randomIds = randomIdDatabase.randomIdDao().getAll();
for (RandomId randomId : randomIds) {
Log.d("IDDATA","name is " + randomId.getName() + " ID is " + randomId.getRandomId());
}
}
}跑得像
D/IDDATA: name is null ID是-9223372036854775808 D/IDDATA: name is null ID为9223372036854775807 D/IDDATA: name is name0 ID为41072993476813590 D/IDDATA: name is name1 ID为22838362508669948 D/IDDATA: name is name10 ID为3903077050951194 D/IDDATA: name10 name100 ID为94821181770704090341/IDDATA:名称为name101 ID为80607588718587575D/IDDATA:名称为name102 ID为320463188743981564 D/IDDATA: name103 ID为3777087074644/ name104 :IDDATA为2846060871858587525D/IDDATA:名称为name1023597159533635558763 D/IDDATA:名称为name107 ID为3199952401843656135 D/IDDATA:名称为name108 ID为47449628201566105 D/IDDATA:名称为name109 ID为48604112123921960369 D/IDDATA:名称为name11 ID为1162315037045532434 D/IDDATA:名称为name110 ID为28071787194055346105 D/IDDATA:名称为name111 ID为3643686187723794393 D/IDDATA:名称为name111 ID为45516415748625814 D/IDDATA:名称为name1132244323676217441072 D/IDDATA: name118 ID为911318293674111436 D/IDDATA:名称为name119 ID为14349150093930897 D/IDDATA:名称为name12 ID为2661856341619735016 .
https://stackoverflow.com/questions/59572749
复制相似问题