【问题标题】:Limit the number of rows in a room database限制房间数据库中的行数
【发布时间】:2017-09-13 09:08:55
【问题描述】:

如何通过删除行中最旧的项目并插入最新的项目来限制 Android 房间数据库中的行数?

我猜它是向数据库添加项目时的标准查询?

编辑:我想将数据库表的最大行数限制为 20。如果达到该限制,我们将删除最旧的项目并通过保留当前行插入新项目数到 20。

【问题讨论】:

  • 解释你想要什么......你想为你的数据库行设置限制,当你想添加新数据并且所有行都有旧数据时,数据库会为第一行添加新数据?或者你会选择特定的行来设置数据???
  • @MohamedNagyMostafa 请查看编辑
  • okey .. 我想了两种方法,首先我可以告诉你技术从 1 到 20 连续插入新数据,所有行都有数据,然后再次重复从 1 插入...但这将是一个好方法,因为您不会在程序期间删除行..因为如果您删除任何行,那么最好的算法是在删除的行中设置新数据。第二种方法,如果您在程序中删除了行,则必须使用列作为插入日期,然后您可以通过按顺序排序检索数据来检查它。告诉我哪个对你好,我会详细解释

标签: java android android-room


【解决方案1】:

这里是示例解决方案:

查询是:

@Query("SELECT * FROM user LIMIT :limit OFFSET :offset")
    User[] loadAllUsersByPage(int limit,int offset);

这里,它会根据限制和偏移量给出一个用户列表。

如果 loadAllUsersByPage(2,0) 它将返回表中的前 2 行。

如果loadAllUsersByPage(2,1) 它将从表中返回第 2 行和第 3 行。

但如果是loadAllUsersByPage(-1,10),那么它将为表中的前 10 行提供服务。

【讨论】:

  • 如果你通过Integer.MAX_VALUE作为限制,那会比没有LIMIT子句的查询性能低吗?
  • @Mark,从技术上讲-是的,因为施加限制可能在内部意味着对数据集进行某种形式的排序,这会影响性能。数据库查询允许多于任何MAX_VALUE(包括多于Long.MAX_VALUE),因此它们通常不会在limit和offset中赋予Integer.MAX_VALUE任何特殊含义。
  • 在 db 中创建表是否有任何限制...我的意思是在一个 db 中可以创建多少表?n 在一个 db 中可以创建多少行?限制?跨度>
【解决方案2】:

我认为您可以将数据插入表中,然后删除除最后 20 行之外的所有行(限制)

要删除,您可以使用以下查询

DELETE FROM tableName where id NOT IN (SELECT id from tableName ORDER BY id DESC LIMIT 20)

在这种情况下,id 是设置为自动递增的主键。如果您按日期存储它们,您也可以使用日期作为键

【讨论】:

  • 这实际上会删除最多 25 行,而 OP 试图保留不超过 25 行
  • 在 db 中创建表是否有任何限制...我的意思是在一个 db 中可以创建多少表?n 在一个 db 中可以创建多少行?限制?跨度>
【解决方案3】:

假设:

你的桌子是

    create table example_table (
      ts timestamp,
      uid number(19),
      some_other_field varchar(64)
    );

而且您不想关心手动运行某些查询。

使用数据库触发器:

    create trigger
      if not exists -- I don't actually know if you DB will support this line.
                    -- Might want to remove it if it's not.
    example_table_limiter
    on example_table
    after insert
    begin
      delete
      from example_table
      where ts in (
        select ts
        from example_table
        order by ts 
        limit -1 -- we don't want to limit how many rows we want to delete
        offset 25 -- but we want to offset query result so it leaves 25 rows in table
      );
    end;

“无限制偏移”语法的灵感来自this answer

在 java 中启用触发器:

简单的 Android,您可以在其中覆盖 SQLiteOpenHelper

    public class DataBaseSchemaHelper extends SQLiteOpenHelper {
      @Override
      public void onCreate(SQLiteDatabase db) {     
        db.execSQL(<trigger string from above>);
      }
    }

Android Room 版本:

     public class MyDatabase extends RoomDatabase {
       @Override
       public void init(DatabaseConfiguration _config) {
         super.init(_config);
         getOpenHelper().getWritableDatabase().execSQL(<trigger string from above>);
       }
     }

【讨论】:

  • 我使用 Android Room 处理 SQL 数据库
  • @x10sion,你仍然可以这样做,只是在稍微不同的地方。我会将其添加到我的答案中。
  • @x10sion,这对你有用吗? (我自己对 Room 并不熟悉)。
【解决方案4】:

您可以通过这样做来限制列/行:此查询将返回新数据并在达到其限制时删除旧数据。

解释:

  1. 第一个查询是按降序选择所有数据顺序
  2. 第二个查询是从列/行 id > 20 中删除数据

如果您希望您的表只有 20 行,则将 OFFSET 设置为 20,LIMIT 表示一次插入和删除的行数。

在我的示例中,当用户输入 1 个新数据时,我删除了 1 行(最旧/最后一行)


  @Query("SELECT * FROM my_table ORDER BY timeStamp DESC")
  fun getAllData(): List<MyEntityClass>

  @Query("DELETE FROM my_table WHERE id IN (SELECT id FROM my_table ORDER BY timeStamp DESC LIMIT 1 OFFSET 20)")
  fun removeOldData()

【讨论】:

    【解决方案5】:

    按照以下步骤操作:

    1> 获取该表的行数

    your_count = SELECT count( * ) FROM table_name;
    

    2> 如果计数>(大于)20 则获取最旧的记录

    SELECT *
      FROM table_name
     ORDER BY entry_Date ASC
     LIMIT 1;
    

    3> 现在删除这些选定的记录

    4> 插入新数据

    注意:如果您要插入多个条目而不是将其放入循环中

    【讨论】:

      猜你喜欢
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 2021-02-11
      • 1970-01-01
      相关资源
      最近更新 更多