如何从数据库中删除所有数据

How to remove ALL data from the database

我想从数据库中删除所有数据(具有自动增量值)。 我用房间。

我在文档中读到了类似 clearAllTables() 的内容,但根据文档:

This does NOT reset the auto-increment value

所以这个方法并不聪明

也没有删除数据库。

为此,我可以从设备中删除文件数据库,但这效率不高。

有什么方法可以从数据库中删除所有具有自动增量值的数据吗?

这很重要,因为如果我删除 10 行,然后我将添加新的 10 行,这些行的 ID 将从 10 开始,而不是从 0 开始。

  1. 您可以在访问数据库之前删除文件,然后访问数据库将创建数据库(可能不是 suitable任何时间).

    • 按文件,如果 WAL(Write-Ahead 日志记录 - 默认值)正在使用,那么除了根据传递给 Room databaseBuilder 的第三个参数的文件之外。可能存在两个附加文件,一个后缀为 -wal,另一个后缀为 -shm。如果存在,也应将其删除。
  2. 您可以使用 clearAllTables 然后获取一个 SupportSQLiteDatabase 并执行一个 execSQL,为每个用户定义 table 使用,或如下使用一个函数(设置在下面测试过) 在 @Dao 注释摘要 class 或接口中:-

    UPDATE sqlite_sequence SET seq = 0 WHERE name = 'the_name_of_the_table';

    • 不是 100% 确定 Room 让你访问 sqlite_sequence,我相信它以前没有,但现在可能会。

    • 你可能没有 WHERE 子句是安全的,在这种情况下,每一行(每行 table 1 与 AUTOINCREMENT 见下文重新 AUTOINCREMENT)将 seq 值设置为 0.

      • 刚刚使用 @Query("UPDATE sqlite_sequence SET seq=0") fun resetSQLiteSequence() 进行了测试,并将 seq 重置为 0。
  3. 您不能使用 autogenerate = true,而是使用 @PrimaryKey val id: Long?=null (Kotlin) 或 @PrimaryKey Long id = null; (Java)。

    • 这仍然会生成一个唯一的 id(通常比最后一个大 1(不保证是否使用 autogenerate = true 或不))。
    • 这实际上是推荐的方式(根据 SQLite),它更有效,因为 sqlite_sequence table 不用于存储 table 的最高分配 rowid .所以插入时不需要获取值也不需要更新。
      • rowid 是每个房间 table(少数除外)都有的一列。当列是整数类型时(Room 给出的列类型为 INTEGER)并且该列是主键,那么该列是 rowid 列的别名。在 https://sqlite.org/autoinc.html
      • 查看更多
    • autogenerate = true所做的一切(SQLite 明智的)是添加 AUTOINCREMENT 关键字 - 再次参见 https://sqlite.org/autoinc.html
    • autogenerate = true 也改变了值的处理,如果值为 0 则将生成 id,否则不会。使用 autogenerate = false,则生成 id 时为 null,其他值按原样使用。

选项 3 是最简单的解决方案,也可能是最安全、最可靠的解决方案。

您评论了:-

I use primary key for building relations inside this db. So I use it for unique identifying items. If you have a huge number of items in db, imagine how big ID will be after a hundred of cleans with keeping old ID

对于 SQLite,rowid 是一个 64 位有符号整数,它可以大到 9223372036854775807。

如果达到该数字,则使用 autogenerate = true aka AUTOINCREMENT 将导致 SQLITE FULL 错误。然而,如果没有,SQLite 将尝试找到一个未分配的 ID(很可能有两个原因 a)你正在删除行并释放 id b)没有设备可能存储那么多数据(当然不是任何 android 设备)) .