如何从数据库中删除所有数据
How to remove ALL data from the database
我想从数据库中删除所有数据(具有自动增量值)。
我用房间。
我在文档中读到了类似 clearAllTables() 的内容,但根据文档:
This does NOT reset the auto-increment value
所以这个方法并不聪明
也没有删除数据库。
为此,我可以从设备中删除文件数据库,但这效率不高。
有什么方法可以从数据库中删除所有具有自动增量值的数据吗?
这很重要,因为如果我删除 10 行,然后我将添加新的 10 行,这些行的 ID 将从 10 开始,而不是从 0 开始。
您可以在访问数据库之前删除文件,然后访问数据库将创建数据库(可能不是 suitable任何时间).
- 按文件,如果 WAL(Write-Ahead 日志记录 - 默认值)正在使用,那么除了根据传递给 Room databaseBuilder 的第三个参数的文件之外。可能存在两个附加文件,一个后缀为
-wal
,另一个后缀为 -shm
。如果存在,也应将其删除。
您可以使用 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。
您不能使用 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 设备)) .
我想从数据库中删除所有数据(具有自动增量值)。 我用房间。
我在文档中读到了类似 clearAllTables() 的内容,但根据文档:
This does NOT reset the auto-increment value
所以这个方法并不聪明
也没有删除数据库。
为此,我可以从设备中删除文件数据库,但这效率不高。
有什么方法可以从数据库中删除所有具有自动增量值的数据吗?
这很重要,因为如果我删除 10 行,然后我将添加新的 10 行,这些行的 ID 将从 10 开始,而不是从 0 开始。
您可以在访问数据库之前删除文件,然后访问数据库将创建数据库(可能不是 suitable任何时间).
- 按文件,如果 WAL(Write-Ahead 日志记录 - 默认值)正在使用,那么除了根据传递给 Room databaseBuilder 的第三个参数的文件之外。可能存在两个附加文件,一个后缀为
-wal
,另一个后缀为-shm
。如果存在,也应将其删除。
- 按文件,如果 WAL(Write-Ahead 日志记录 - 默认值)正在使用,那么除了根据传递给 Room databaseBuilder 的第三个参数的文件之外。可能存在两个附加文件,一个后缀为
您可以使用
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。
- 刚刚使用
您不能使用
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.htmlautogenerate = 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 设备)) .