如何在android中通过room删除数据库元数据?

如何在android中通过room删除数据库元数据?,android,sqlite,android-sqlite,android-room,Android,Sqlite,Android Sqlite,Android Room,我在房间数据库中有一个表,其中一个字段设置为index,它是autoincrementSqlite将在其主表中保存一些元数据,以保持上次自动生成值的计数 根据我的应用程序逻辑,我将清除数据库并保留结构;假设我向数据库中插入了3个项目,并且发生了上述操作,因此我清除了项目,但当我插入一个新项目时,其自动生成的字段将为4,从长远来看,这将导致溢出和应用程序崩溃。我通过删除autoincrement并手动设置字段来解决这个问题 现在我的问题是,如何在每次数据库清除后将自动递增字段值重置为1(我更喜欢仅

我在房间数据库中有一个表,其中一个字段设置为
index
,它是
autoincrement
Sqlite
将在其主表中保存一些元数据,以保持上次自动生成值的计数

根据我的应用程序逻辑,我将清除数据库并保留结构;假设我向数据库中插入了3个项目,并且发生了上述操作,因此我清除了项目,但当我插入一个新项目时,其自动生成的字段将为4,从长远来看,这将导致溢出和应用程序崩溃。我通过删除
autoincrement
并手动设置字段来解决这个问题


现在我的问题是,如何在每次数据库清除后将自动递增字段值重置为1(我更喜欢仅限房间的方式)?

自动递增的工作方式是在确定新值时使用两个值:-

  • 第一种方法相当于使用
    max(自动增量列)
    (即为已自动增量编码的rowid列添加别名的列)
  • 第二个是从表sqlite_序列中获得的,该表是从名称列中包含表名的行的seq列中获得的

    • 请注意,这些值不是存储在主表sqlite_master(模式)中,而是存储在sqlite_sequence表中
    • sqlite_序列表仅在使用自动增量时才存在
将1添加到较大的值中

理论上,要重置,应该从表中删除所有行,并从sqlite\u序列中删除相应的行

但是,房间可以保护系统表。因此,简言之,似乎没有办法利用空间来做后一件事,这就是问题所在必须在房间外(之前)运行,因此受到限制

  • 注意在答案中有额外的代码用于从0(触发器)开始编号
但是,就溢出而言,基本上不太可能:-

  • 表中的最大行数
  • 表中的理论最大行数为2乘以64的幂 (18446744073709551616或约1.8e+19)。这个限制是无法达到的 因为将达到140 TB的最大数据库大小 第一。一个140 TB的数据库只能容纳大约 1e+13行,并且仅当没有索引且每行 包含的数据很少。

    自动递增时,它是2到63的幂次方(9223372036854775808‬) (如果没有自动增量,您可以使用负值(java),这样您就可以使用第64位,因此是最大值),因此限制可能是磁盘容量,而不是达到的最高id

    附加的 在玩了一些游戏之后,在Room拥有数据库的情况下,以下内容确实会重置序列

    也就是说,以下构建文件室数据库将插入两行,重置序列(包括删除最近添加的行)

    • 通过将数据库作为标准SQLiteDatabase打开
      • 请注意OPENREADWRITE和EnableWriteHeadLogging的使用
      • (如果不是后者,则会显示一条警告消息,说明无法关闭WAL,因为db处于打开状态,因此这只是在WAL模式下打开)
    • 删除表中的现有行并
    • 从sqlite_序列中删除相应的行,最后
    • 正在关闭另一个数据库
    :-

    该表的实体为:-

    @Entity(tableName = MainActivity.MYTABLENAME)
    public class MyTable {
        @PrimaryKey(autoGenerate = true)
        private long id;
        private String name;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    这里回答了这个问题:简而言之,您必须手动执行这些查询:
    deleteofromsequenceAction;
    deleteofromsqlite\u序列,其中name='SequenceAction';
    AUTOINCREMENT的全部要点是永远不要重用自动生成的rowid。只需将其从
    整数主序列中删除即可如果您不希望出现这种行为,请输入列定义(尽管如果使用它会导致应用程序崩溃,您会遇到一些严重问题)@Shawn它的要点不是重复使用特定的表和表事务,而不是生命周期。但是,
    自动增量
    的最大限制约为2147483648,如果表使用大量事务,从长远来看它将溢出。2147483648?试试9223372036854775807。这是一个有符号的64位整数。你永远不会使用c除非你手动插入那么大的rowid,否则我可能会有点接近。但是,是的,关键是在给定表的生命周期内永远不要重用rowid。请参阅。如果你不关心rowid是否可以重用,请不要使用
    自动增量
    。好吧,谢谢@Shawn,我认为它是32位的。谢谢,如果没有人给出更好的答案,我会接受它。
    @Entity(tableName = MainActivity.MYTABLENAME)
    public class MyTable {
        @PrimaryKey(autoGenerate = true)
        private long id;
        private String name;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }