2012-04-14 49 views
2

我有一个sqlite数据库(在android上),我想存储一些数据的最新N条目。保持最新的n条目在表

表的主键是日期字段。基本上,每当我在达到阈值后插入一行时,我想从表中删除最旧的条目。

有没有特别聪明/很好的方法来做到这一点?请注意,每次插入后我都会检查不变量(nr行< = THRESHOLD),所以我们不必处理任何事情,只需删除最早的条目即可。

什么我打算做的主要是:

  1. 插入数据
  2. 如果表中的COUNT(*)< =门槛:转到4
  3. DELETE FROM表WHERE日期==(SELECT按日期排序的日期ASC LIMIT 1);
  4. DONE

注意我使用ORMlite,但因为有参与,我可以只使用原始的SQL没有用户数据,所以不应该是一个问题。

+0

这不违反单值子查询规则吗? 3.DELETE FROM table WHERE date ==(SELECT date from table order by date ASC); – 2012-04-14 22:35:56

+0

@Chris在那里应该至少有一个限制1。但它应该被视为伪代码 - 我仍在考虑如何最好地实现它 - 我只是认为一些代码会使它更容易理解。 – Voo 2012-04-14 22:37:55

回答

1

添加新行并且行数超过阈值时,可以使用触发器删除最旧的行。

行数可以保存在一个单独的会计表中,以避免每个插入COUNT。

这里有一个完整的例子:

create table bookkeepings (bk_name text primary key, bk_value integer not null); 

insert or replace into bookkeepings values ('Max Results', 50); 
insert or replace into bookkeepings values ('Qty Results', 0); 

create table results 
    (r_timestamp text primary key default (datetime(current_timestamp)), 
    result text); 

create trigger results_limit_trigger before insert on results" 
    for each row" 
    when (select bk_value from bookkeepings where bk_name = 'Qty Results') 
    >= (select bk_value from bookkeepings where bk_name = 'Max Results') 
    begin 
    delete from results 
     where r_timestamp = (select r_timestamp from results order by r_timestamp limit 1); 
    end; 

create trigger results_count_insert_trigger after insert on results 
    for each row 
    begin 
    update bookkeepings set bk_value = bk_value + 1 where bk_name = 'Qty Results'; 
    end; 

create trigger results_count_delete_trigger after delete on results 
    for each row 
    begin 
    update bookkeepings set bk_value = bk_value - 1 where bk_name = 'Qty Results'; 
    end; 
2
DELETE FROM table WHERE date = (SELECT MAX(date) from table LIMIT 1); 
+0

Ah MAX是一个好主意,是的 - 意图更清晰,最有可能更快。但总体结构不能改善?不得不为此做4个查询似乎很迂回。 – Voo 2012-04-14 22:45:19

+1

为什么插入和删除?也许在MIN(日期时间)的UPDATE用新数据和当前日期时间覆盖最旧的条目? – Sam 2012-04-14 22:47:48

+0

@Sam有趣的想法。从来没有想过更新完整的记录。可能不会比插入/删除效率更高(因为我们仍然需要重新排序表),但我也会尝试。 – Voo 2012-04-14 22:56:03

1

这个怎么样?

-- keep the last N records by expiration date 
declare @expDate datetime 

set @expDate = (select top 100 max(dt) from table order by dt asc); 
delete from table where dt > @expDate